JAL Language Syntax Reference - Index

JAL Language Syntax Reference

This documentation covers the JAL (Just Another Language) programming language syntax. Click on any topic below to view detailed information.

Syntax Topics

  • DEBUG
  • ERROR
  • USEC DELAY
  • WARN
  • ALIAS
  • ARRAYS
  • ASCII ESCAPE SEQUENCES
  • ASM ASSEMBLER
  • ASSEMBLY MACROS
  • ASSEMBLY OP-CODES
  • ASSERT
  • AT PLACEMENT
  • BANK PAGE
  • BLOCK
  • CASE
  • CASTING
  • COMMENTS
  • COMPILER OPTIONS
  • CONST CONSTANTS
  • CONSTANT ARRAYS
  • COUNT
  • DATA DIRECTIVES DBDWDS
  • DEFINED
  • ELSIF ELSE
  • EXIT LOOP
  • EXPRESSIONS
  • FAST INTERRUPTS
  • FLOATING POINT
  • FOR
  • FOREVER
  • IDENTIFIERS
  • IF
  • IN OUT IN OUT
  • INCLUDE
  • INTERRUPTS
  • LOCAL LABELS
  • LOOP
  • MULTIPLICATION DIVISION
  • NAMED CONSTANTS
  • NUMERIC SEPARATORS
  • OPERATOR PRECEDENCE
  • OPERATORS
  • OTHERWISE
  • PRAGMA
  • PRAGMA KEEP
  • PRAGMA TARGET
  • PROCEDURES FUNCTIONS
  • PROMOTION RULES
  • PSEUDO-VARIABLES
  • RECORD STRUCTURES
  • REPEAT
  • RETURN
  • SCOPE
  • SHARED KEYWORD
  • STRING LITERALS
  • TASK START SUSPEND
  • TASKS
  • TYPES
  • UNNAMED CONSTANTS
  • UNTIL
  • USING IN FOR
  • VAR VARIABLES
  • VOLATILE KEYWORD
  • WHEREIS
  • WHILE

Generated by JAL Syntax Documentation System | Source: DITA


Comments - JAL Language Syntax Reference

Comments JALV2 SYNTAX

Syntax

-- comment
; comment

Description

Comments begin with '--' or ';' and continue to end of line.

Notes

Both styles equally valid. Choose one for consistency.

Example

VAR BYTE counter = 0  -- initialize
; This is also a comment

Generated by JAL Syntax Documentation System | Source: DITA


Identifiers - JAL Language Syntax Reference

Identifiers JALV2 SYNTAX

Syntax

letter_or_underscore
[letters_digits_underscores...]

Description

Names for variables, constants, procedures, etc. Must start with letter or '_'. Case insensitive. Identifiers starting with '_' reserved for compiler.

Notes

JAL is case insensitive.

Example

VAR BYTE my_variable
VAR BYTE MyVariable  -- same identifier

Generated by JAL Syntax Documentation System | Source: DITA


accelerometer_gyroscope_bmi160.jal - JALLIB Library Documentation

accelerometer_gyroscope_bmi160.jal JALLIB LIBRARY

Title

Accelerometer & Gyroscope BMI160

Author

Matthew Schinkel, copyright (c) 2017, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides routines to read x,y,z values from
BMI160's accelerometer & gyroscope using SPI.

Notes

This device also supports I2C, but I have not added support in this lib.
My testing was done with a small 12 pin board from ebay.
connections are as follows:
PIC / BMI160
SDO -> SDA
SDI -> SAO
SS -> CS
SCK -> SCL
N/A -> SDX
N/A -> SCX
N/A -> INT1
N/A -> INT2
N/A -> OCS

Sources

http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf

Constants and Variables

BMI160_READ - const byte = 0x80
BMI160_WRITE - const byte = 0x00
BMI160_REG_DEVICE_ID - const byte = 0x00
BMI160_REG_ACC_RANGE - const byte = 0x41
BMI160_REG_GYR_RANGE - const byte = 0x43
BMI160_REG_CMD - const byte = 0x7E
BMI160_REG_STATUS - const byte = 0x1B
BMI160_SOFT_RESET - const byte = 0xB6

Routines

  • bmi160_init - Procedure
  • bmi160_read_reg - Function returns byte
  • bmi160_write_reg - Procedure
  • bmi_160_accelerometer_x - Function returns word
  • bmi_160_accelerometer_y - Function returns word
  • bmi_160_accelerometer_z - Function returns word
  • bmi_160_communication_test - Function returns bit
  • bmi_160_gyro_x - Function returns word
  • bmi_160_gyro_y - Function returns word
  • bmi_160_gyro_z - Function returns word


Types - JAL Language Syntax Reference

Types JALV2 SYNTAX

Syntax

BIT (1 bit: 0..1)
BYTE (8 bits: 0..255)
SBYTE (8 bits signed: -128..127)
WORD (16 bits: 0..65535)
SWORD (16 bits signed: -32768..32767)
DWORD (32 bits: 0..4294967295)
SDWORD (32 bits signed)
FLOAT (floating point)

Description

JAL provides built-in types for different sizes and signedness.

Notes

Choose the smallest type that fits your data to save memory.

Example

VAR BIT flag = TRUE
VAR BYTE counter = 0
VAR WORD temperature = 250
VAR FLOAT pi = 3.14159

Generated by JAL Syntax Documentation System | Source: DITA


Arrays - JAL Language Syntax Reference

Arrays JALV2 SYNTAX

Syntax

VAR [ VOLATILE ] [ SHARED ] type [ '*' cexpr ] identifier
    [ '[' [ cexpr ] ']' ]                    -- Array dimension
    [ { AT cexpr [ ':' bit ]
      | var [ ':' bit ]
      | '{' cexpr1 [ ',' cexpr2 ... ] '}'
      | IS var
      } ]                                    -- Placement
    [ '=' { cexpr
          | '{' cexpr1 [ ',' ... ] '}'
          | '"' ... '"'
          } ]                                -- Initialization
    [ ',' identifier ... ]                   -- Multiple variables

Description

Declares an array variable.

Notes

Arrays must fit within a single PIC data bank. BIT arrays not supported.

Example

VAR BYTE data[10]
VAR BYTE values[] = {1, 2, 3, 4, 5}

Generated by JAL Syntax Documentation System | Source: DITA


RECORD (Structures) - JAL Language Syntax Reference

RECORD (Structures) JALV2 SYNTAX

Syntax

RECORD identifier IS
type field1
type field2
END RECORD

Description

Defines a record (structure) type that groups related data together.

Notes

Records allow organizing related data. Fields are accessed using the dot (.) operator.

Example

RECORD point IS
    WORD x
    WORD y
END RECORD

Generated by JAL Syntax Documentation System | Source: DITA


ALIAS - JAL Language Syntax Reference

ALIAS JALV2 SYNTAX

Syntax

ALIAS identifier IS identifier1

Description

Creates an alias (alternative name) for an existing variable or constant. The alias refers to the same memory location as the original.

Notes

Aliases are useful for giving meaningful names to hardware registers.

Example

VAR BYTE port_register
ALIAS led_status IS port_register

Generated by JAL Syntax Documentation System | Source: DITA


VAR (Variables) - JAL Language Syntax Reference

VAR (Variables) JALV2 SYNTAX

Syntax

VAR [ VOLATILE ] [ SHARED ] type [ '*' cexpr ] identifier
    [ '[' [ cexpr ] ']' ]                    -- Array dimension
    [ { AT cexpr [ ':' bit ]
      | var [ ':' bit ]
      | '{' cexpr1 [ ',' cexpr2 ... ] '}'
      | IS var
      } ]                                    -- Placement
    [ '=' { cexpr
          | '{' cexpr1 [ ',' ... ] '}'
          | '"' ... '"'
          } ]                                -- Initialization
    [ ',' identifier ... ]                   -- Multiple variables

Description

Declares a variable. Variables can be simple types, arrays, or complex structures. The VOLATILE keyword prevents optimization. SHARED indicates the variable is in shared memory. Variables can be placed at specific memory locations using AT.

Notes

Variables defined in a block scope are only visible within that block.

Example

VAR BYTE counter = 0
VAR WORD temperature
VAR BIT led_state = FALSE
VAR BYTE data[10]
VAR BYTE message[] = "Hello"

Generated by JAL Syntax Documentation System | Source: DITA


CONST (Constants) - JAL Language Syntax Reference

CONST (Constants) JALV2 SYNTAX

Syntax

CONST type identifier = cexpr

Description

Declares a named constant. Constants must be initialized with a constant expression that can be evaluated at compile time.

Notes

Constants cannot be modified during program execution.

Example

CONST BYTE MAX_COUNT = 100
CONST WORD PI = 314
CONST BYTE MESSAGE[] = "Error"

Generated by JAL Syntax Documentation System | Source: DITA


ASCII Escape Sequences - JAL Language Syntax Reference

ASCII Escape Sequences JALV2 SYNTAX

Syntax

\n \r \t \b \f \v \a \xHH \oOOO \zBBB \\

Description

Special characters in strings. \n=newline, \r=return, \t=tab, \xHH=hex, \oOOO=octal, \zBBB=binary, \\=backslash.

Notes

Work in both strings and character constants.

Example

VAR BYTE msg[] = "Hello\nWorld"
VAR BYTE hex = "\x41"

Generated by JAL Syntax Documentation System | Source: DITA


Numeric Separators - JAL Language Syntax Reference

Numeric Separators JALV2 SYNTAX

Syntax

Underscores '_' in numbers

Description

Underscores ignored in numeric constants, useful for grouping.

Notes

Improves readability of large numbers.

Example

CONST DWORD big = 1_000_000
CONST BYTE flags = 0b1111_0000

Generated by JAL Syntax Documentation System | Source: DITA


Unnamed Constants - JAL Language Syntax Reference

Unnamed Constants JALV2 SYNTAX

Syntax

12 (decimal), 0x12 (hex), 0b01 (binary), 0q01 (octal), "a" (ASCII), 1.23 (float)

Description

Numeric constants in various formats.

Notes

UNIVERSAL constants auto-convert to needed type.

Example

VAR BYTE x = 255
VAR BYTE y = 0xFF
VAR FLOAT pi = 3.14159

Generated by JAL Syntax Documentation System | Source: DITA


Constant Arrays - JAL Language Syntax Reference

Constant Arrays JALV2 SYNTAX

Syntax

CONST
type
identifier
[size]
 = {
values
...}

Description

Arrays in CODE space, not DATA. Max 255 elements. Only use space if indexed with non-constant.

Notes

Saves RAM by using program memory.

Example

CONST BYTE lookup[] = {0, 1, 4, 9, 16}
result = lookup[3]

Generated by JAL Syntax Documentation System | Source: DITA


String Literals - JAL Language Syntax Reference

String Literals JALV2 SYNTAX

Syntax

"text"

Description

String literals assign ASCII values to byte arrays.

Notes

No terminating NUL unless explicitly added. Introduced in JALv2.4p.

Example

VAR BYTE message[] = "Hello"

Generated by JAL Syntax Documentation System | Source: DITA


Operators - JAL Language Syntax Reference

Operators JALV2 SYNTAX

Syntax

Arithmetic: +, -, *, /, %
Logical: !, !!, ==, !=, <, <=, >, >=
Bitwise: &, |, ^, <<, >>
Special: COUNT, WHEREIS, DEFINED

Description

JAL supports arithmetic, comparison, bitwise, and special operators.

Notes

Multiplication and division are expensive. Use shifts for powers of 2.

Example

result = 10 + 20
IF result > 25 THEN
    result = result << 1
END IF

Generated by JAL Syntax Documentation System | Source: DITA


Promotion Rules - JAL Language Syntax Reference

Promotion Rules JALV2 SYNTAX

Syntax

Automatic type conversion in expressions

Description

FLOAT wins over all. UNIVERSAL matches other operand. Same width: unsigned wins. Different width: wider wins.

Notes

Understanding promotion prevents truncation bugs.

Example

VAR BYTE b = 10
VAR WORD w = 20
result = b + w  -- b promoted to WORD

Generated by JAL Syntax Documentation System | Source: DITA


Casting - JAL Language Syntax Reference

Casting JALV2 SYNTAX

Syntax

type(expression)

Description

Converts a value from one type to another.

Notes

Cast when types differ to avoid warnings and ensure correct results.

Example

yy = BYTE(xx)
xx = WORD(bb) * WORD(bb)

Generated by JAL Syntax Documentation System | Source: DITA


Expressions - JAL Language Syntax Reference

Expressions JALV2 SYNTAX

Syntax

variable = value operator value

Description

Values combined with operators.

Notes

Understand operator precedence and casting.

Example

y = x + y
y = (5 + (3 - 2 * x)) / z

Generated by JAL Syntax Documentation System | Source: DITA


ls7366r_read_counter - JALlib Procedures Help

ls7366r_read_counter JALLIB FUNCTION

Signature

function ls7366r_read_counter() return dword is

Description

Read the counter

Include

To use this procedure, include the library:

include quadrature_counter_ls7366r

Parameters

None

Return Value

None

Example

From sample file: 18f4620_quadrature_counter_ls7366r.jal

-- Title: Quadrature Counter ls7366r
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler:2.4q6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: ls7366r is a quadrature encoder counter for counting or
--              keeping track of the position of a optical rotary encoder
--              or linear slide. This device can count signals of TTL type
--              (pulses 90 degrees out of phase) or signals with
--              up/down direction and clock signals. TTL mode is default
--              in this lib.
--
-- Notes:
--     Use ls7366r_write(WRITE_MDR0, 0x00) after init() for
--     devices with up/down direction and count clock outputs (not tested).
--
-- Sources:
-- https://lsicsi.com/datasheets/LS7366R.pdf
--
-- This file has been manually generated.
--

include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a0
alias led_direction is pin_a0_direction
led_direction = output

-- setup ls7366r
-- setup spi chip select pin
ALIAS ls7366r_chip_select             is pin_ss
ALIAS ls7366r_chip_select_direction   is pin_ss_direction
-- initial settings
ls7366r_chip_select_direction = output -- chip select/slave select pin
ls7366r_chip_select = high             -- start chip slect high (chip disabled)
alias ls7366r_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
-- Include and init
include quadrature_counter_ls7366r
ls7366r_init()
;ls7366r_write(WRITE_MDR0, 0x00) -- for devices with up/down direction and clock signals

-- Test communication
if ls7366r_read(LS7366R_READ_MDR0) == 3 then ;read what was set in init procedure
   print_string(serial_data,"LS7366R Loaded OK")
else
   print_string(serial_data,"LS7366R communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   -- Report current count/position
   print_dword_dec(serial_data,ls7366r_read_counter())
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: quadrature_counter_ls7366r.jal


DEFINED - JAL Language Syntax Reference

DEFINED JALV2 SYNTAX

Syntax

DEFINED(identifier)

Description

Returns TRUE if identifier exists, FALSE otherwise. Compile-time evaluation.

Notes

Useful for conditional compilation and library compatibility.

Example

IF DEFINED(debug_mode) THEN
    _DEBUG "Debug enabled"
END IF

Generated by JAL Syntax Documentation System | Source: DITA


WHEREIS - JAL Language Syntax Reference

WHEREIS JALV2 SYNTAX

Syntax

WHEREIS(identifier)

Description

Returns memory location. Procedures/functions return CODE address. Variables return DATA address.

Notes

For low-level programming. Cannot use with simple constants.

Example

addr = WHEREIS(my_var)

Generated by JAL Syntax Documentation System | Source: DITA


EXIT LOOP - JAL Language Syntax Reference

EXIT LOOP JALV2 SYNTAX

Syntax

EXIT LOOP

Description

Immediately exits from the current loop.

Notes

Can be used in any loop type for early exit.

Example

FOREVER LOOP
    IF counter > 100 THEN
        EXIT LOOP
    END IF
END LOOP

Generated by JAL Syntax Documentation System | Source: DITA


flash_erase_block - JAL Language Syntax Reference

flash_erase_block SYNTAX

Description:
-- Procedures and fuctions to read/erase/write flash (code) memory of 18FxxJxx. -- . -- Since erase of flash memory is required before writes and 1024 bytes are -- erased at a time with these PICs, a 1 KB block of flash must be reserved, -- and it must be on a 1KB boundary (10 LSbits of address must be zero). -- Limitations to choose a proper address are: -- - The program is located in low memory -- - The highest bytes of flash memory contain the configuration bits -- of many 18F PICs, including the J-series -- So both the lowest and the highest 1KB of code memory are not usable for -- the purpose of storing data. -- The one but highest 1K block of code memory seems the only choice! -- Beware that the program is not so big that it occupies this address. -- The location is also PIC dependent, so when changing PIC change the address! -- . -- Since flash memory is written 64 bytes at a time the block of data memory to -- be saved in flash memory must be a multiple of 64 bytes. The way to do this -- is by declaring an array of bytes (a multiple of 64) and declare the variables -- as overlay of this array. -- . -- Before including this library you have to specify: -- . -- - The address of the block of flash memory where to save your data, e.g.: -- . -- const byte*3 FLASH_RESERVED = 0x00F800 -- one but highest 1KB block -- -- for a PIC with 64KB flash -- . -- - An array named 'flash_data' containing the data -- you want to save to and restore from flash memory, e.g.: -- . -- var byte flash_data[128] -- block to save in flash memory -- . -- This array may be smaller than 1KB, but not larger! -- (The JALV2 compiler doesn't support arrays larger than 256 bytes)! -- . -- Available procedures/functions: -- flash_erase_block() - erase the 1KB block of flash memory -- flash_read_word() - read a word (2 bytes) of flash memory -- flash_restore_block() - restore the block of memory from flash memory -- flash_save_block() - save the block of data memory to flash memory -- -- Sources: --

Notes

-- Limitations of this library: -- - Only PICs of type 18FxxJyy are supported (and only some are tested). -- - Maximum size of data block to be saved is 1024 bytes. -- -- ===================================================================== -- ---------- Some sanity checks ---------------- if PICTYPE[5] != "J" then _error "Only PICs of type 18FxxJyy are supported by this library" end if if !defined(FLASH_RESERVED) then _error "Address of reserved block of flash memory not defined" end if if ( (FLASH_RESERVED & 0b11_1111_1111) != 0 ) then _error "Reserved block of flash memory must be at 1KB boundary" end if if ( ((count(flash_data) & 0b11_1111) != 0) | -- multiple of 64 (count(flash_data) > 1024) ) then -- maximum size _error "Variable 'flash_data' must be a multiple of 64 bytes and not more than 1024" end if -- ------------------------------------------------------- -- Erase row (1KB) of flash memory -- Arguments: - none -- Returns: - nothing -- Notes: - The reserved block of 1KB flash memory is erased -- -------------------------------------------------------

Generated by JAL Syntax Documentation System | Source: DITA


CASE - JAL Language Syntax Reference

CASE JALV2 SYNTAX

Syntax

CASE expr OF
    cexpr [ ',' cexpr ... ] ':' statement
    [ cexpr [ ',' cexpr ... ] ':' statement
      ... ]
    [ OTHERWISE statement ]
END CASE

Description

Example

CASE xx OF
14

Generated by JAL Syntax Documentation System | Source: DITA


OTHERWISE - JAL Language Syntax Reference

OTHERWISE JALV2 SYNTAX

Syntax

OTHERWISE statement

Description

Default case in CASE statement.

Notes

Like 'default' in C. Optional in CASE statements.

Example

CASE value OF
    1: action1
    OTHERWISE default_action
END CASE

Generated by JAL Syntax Documentation System | Source: DITA


format_sword_dec_length - JALlib Procedures Help

format_sword_dec_length JALLIB PROCEDURE

Signature

procedure format_sword_dec_length(volatile byte out device, sword in data,

Description

writes decimal formatted signed word to output device
output can be specified in length of string and position
values -32767 to +32768, so lenght = 5 max
last digit is position 0, first is 4 = max
32768, len=3, pos=2 gives 327
32768, len=1, pos=0 gives 6
32768, len=2, pos=4 gives 32
added by Eur van Andel, eur@fiwihex.nl, 23 NOV 2009

Include

To use this procedure, include the library:

include format

Parameters

None

Return Value

None

Example

From sample file: 18f452_pressure.jal

-- Title: 18f452_pressure, sample program for sdp600 Sensirion pressure sensor
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2012
-- Adapted-by:
-- Compiler: =2.40
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: usage of SDP600 I2C pressure sensor library
-- Has both serial and LCD output
--
-- This file has been generated by hand (manually maintained)
--

-- include chip
include 18f452					   -- target picmicro, running at 3V3
pragma target clock 10_000_000	   -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS			   -- HS crystal or resonator
pragma target WDT  CONTROL		   -- no watchdog
pragma target LVP  enabled 		   -- allow Low Voltage Programming

-- LCD & 4x4 keyboard
var bit lcd_sterm_pin is pin_c2		-- Sterm LCD & keyboard
var bit lcd_sterm_pin_dir is pin_c2_direction
const LCD_ROWS = 4
const LCD_CHARS = 20
include lcd_sterm_master

-- i2c protocol for sensor
const word _i2c_bus_speed = 1 ; 100 kHz
const bit _i2c_level = true	  ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl			 is pin_scl
alias i2c_scl_direction	 is pin_scl_direction
alias i2c_sda			 is pin_sda
alias i2c_sda_direction	 is pin_sda_direction
--
include i2c_software
i2c_initialize()

const down  = 0
const green = 1
const red   = 2

var bit led     is pin_c5		   -- red and green LED
var bit led_dir is pin_c5_direction
led_dir = output                 -- so green at startup
led = high

procedure leds(byte in x) is     -- two leds in series with two diodes betw +3V3 and GND
   if x == down then             -- 2*1.7V+2*0.6V = 4.6V Vf, they will not light up
      led_dir  = input           -- PIC pin is tied to the middle, via 100 Ohm resistor
   elsif x == red then           -- so HIGH will light lower green LED
      led_dir  = output          -- LOW will light upper RED led
      led      = low             -- pin_direction = input will light no LEDs.
   elsif x == green then
      led_dir  = output
       led     = high
   end if
end procedure

include delay

-- serial output too
const serial_hw_baudrate  = 57600
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

include print           -- print to serial port and LCD
include format          -- format numbers on LCD and serial port

var sword raw_press     -- raw data from sensor
var sword pressure      -- in Pascal

var byte loop_counter
var bit toggle

include sdp600

procedure display() is

   lcd_cursor_position(0,0)   -- LINE 1
   lcd = "r" lcd = "a" lcd = "w" lcd = ":"
   format_sword_dec_length(lcd, raw_press, true, 7, 0)
   lcd = " "                        --
   lcd = " "                        --

   lcd_cursor_position(1,0)  -- LINE 2
   lcd = "p" lcd = "r" lcd = "e" lcd = "s" lcd = "s" lcd = "u" lcd = "r" lcd = "e" lcd = ":"
   print_sword_dec(lcd, pressure)
   lcd = " "                        --

   lcd_cursor_position(2,0)   -- LINE 3
   print_byte_dec(lcd, loop_counter)         -- fan
   lcd = " "                        --
   lcd = " "                        --

   lcd_cursor_position(3,0)   -- LINE 4

end procedure

-- start of main program

for 5 loop
   leds(red)
   delay_100ms(2)
   leds(green)
   delay_100ms(2)
   lcd_clear_screen()  -- reset Sterm
end loop

--                   12345678901234567890
const byte str7[] = "SDP600 pressure test"

lcd_cursor_position(0,0)    -- first line on LCD
print_string(lcd, str7)

print_string(serial_hw_data, str7)
serial_hw_data = ASCII_LF
serial_hw_data = ASCII_CR
serial_hw_data = ASCII_LF           -- empty line
serial_hw_data = ASCII_CR

delay_1s(3)

lcd_clear_screen()  -- reset Sterm

forever loop -- MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM  M A I N   L O O P   MMMMMMMMMMMMMMMMMMMMM

   display

   raw_press = sdp600_read_press_raw()
   pressure = sdp600_read_press_pa()

   delay_100ms(2)    -- for visibility of display

   loop_counter = loop_counter + 1

   if loop_counter % 10 == 0 then       -- every 2 seconds
       serial_hw_data = "r" serial_hw_data = "a" serial_hw_data = "w" serial_hw_data = ":"
       format_sword_dec_length(serial_hw_data, raw_press, true, 7, 0)
       serial_hw_data = " "                        --

       serial_hw_data = "p" serial_hw_data = "r" serial_hw_data = "e"
       serial_hw_data = "s" serial_hw_data = "s" serial_hw_data = "u"
       serial_hw_data = "r" serial_hw_data = "e" serial_hw_data = ":"
       print_sword_dec(serial_hw_data, pressure)
       serial_hw_data = ASCII_LF           -- empty line
       serial_hw_data = ASCII_CR

   end if

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

end loop    -- end of main loop

Generated by JALlib CHM Help System | Source: format.jal


USING (in FOR) - JAL Language Syntax Reference

USING (in FOR) JALV2 SYNTAX

Syntax

FOR expr
    [ USING var ]
    LOOP
    statement_block
    [ EXIT LOOP ]
END LOOP

Description

Loop counter variable in FOR loops. Starts at 0, increments to expression.

Notes

On normal exit, variable equals expression. After EXIT LOOP, keeps start value.

Example

FOR 10 USING i LOOP
    data[i] = 0
END LOOP

Generated by JAL Syntax Documentation System | Source: DITA


FOREVER - JAL Language Syntax Reference

FOREVER JALV2 SYNTAX

Syntax

FOR expr
    [ USING var ]
    LOOP
    statement_block
    [ EXIT LOOP ]
END LOOP

Description

statement_block [ EXIT LOOP ] END LOOP statement_block is executed forever unless [EXIT LOOP] is encountered, in which case the loop is immediately terminated. This is commonly used for the main loop in a program because an embedded program like this never ends.

Example

xx = 5
yy = 6
FOREVER LOOP
READ_ADC()
CHANGE_SPEED()
IF (speed == 5) THEN
EXIT LOOP
END IF
END LOOP
16

Generated by JAL Syntax Documentation System | Source: DITA


ELSIF / ELSE - JAL Language Syntax Reference

ELSIF / ELSE JALV2 SYNTAX

Syntax

ELSIF lexpr THEN
ELSE

Description

Used with IF statements. ELSIF provides additional conditions. ELSE provides a default block.

Notes

Any number of ELSIF clauses can be used.

Example

IF x < 10 THEN
    y = 1
ELSIF x < 20 THEN
    y = 2
ELSE
    y = 3
END IF

Generated by JAL Syntax Documentation System | Source: DITA


shift_register_74595.jal - JALLIB Library Documentation

shift_register_74595.jal JALLIB LIBRARY

Title

shift_register_74595

Author

Joep Suijs, Copyright (C) 2014 .. 2014 Joep Suijs, Adapted-by:

Compiler

>=2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Control of 74595 shift register
.
Setup:
alias sr_scl is pin_d2 ; SRCK (serial clock, rising egde)
alias sr_g is pin_d3 ; G (output enable, low = enable)
alias sr_sda is pin_d1 ; SER_IN / DS
alias sr_rck is pin_d3 ; RCK (parallel clock / load, rising edge)
--
include shift_register_74595
sr_output_enable(1) ; activate shift register outputs --
--
Use:
--
-- set one output of each shift register
sr_write(data) ; data for 74595 - end of chain
-- sw_write for all intermediate 74595 here
sr_write(data) ; data for 74595 #1 (directly connected to PIC)
sr_commit() ; clock all data to outputs
This file has been generated by hand (manually maintained)
TODO:
--------------------------------------------------------------------

----------------------------------------------------------------------------
sr_write - write one byte of data to chip
----------------------------------------------------------------------------
----------------------------------------------------------------------------

Routines

  • sr_commit - Procedure
  • sr_output_enable - Procedure
  • sr_write - Procedure


dfplayer_start_repeat_play - JALlib Procedures Help

dfplayer_start_repeat_play JALLIB PROCEDURE

Signature

procedure dfplayer_start_repeat_play() is

Description

Start the repeat playback of all tracks

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


UNTIL - JAL Language Syntax Reference

UNTIL JALV2 SYNTAX

Syntax

REPEAT
    statement_block
UNTIL logical_expression

Description

Marks end of REPEAT loop and exit condition.

Notes

REPEAT loops always execute at least once.

Example

REPEAT
    counter = counter + 1
UNTIL counter >= 10

Generated by JAL Syntax Documentation System | Source: DITA


WHILE - JAL Language Syntax Reference

WHILE JALV2 SYNTAX

Syntax

WHILE lexpr LOOP
    statement_block
    [ EXIT LOOP ]
END LOOP

Description

statement_block [ EXIT LOOP ] END LOOP statement_block will be executed as long as lexpr evaluates to a 1, or until [EXIT LOOP] is encountered. This is similar to REPEAT above, the difference being the statement_block of REPEAT loop will always execute at least once, whereas that of a WHILE loop may never execute (because the test is done ﬁrst).

Example

WHILE no_button LOOP
xx = xx + 1
IF (xx == 10) THEN
EXIT LOOP
END IF
18

Generated by JAL Syntax Documentation System | Source: DITA


IN / OUT / IN OUT - JAL Language Syntax Reference

IN / OUT / IN OUT JALV2 SYNTAX

Syntax

type IN parameter
type OUT parameter
type IN OUT parameter

Description

Parameter directions. IN=read-only (pass by value), OUT=write-only (return value), IN OUT=both (pass by reference).

Notes

IN copied on entry, OUT written on return, IN OUT both.

Example

PROCEDURE swap(BYTE IN OUT a, BYTE IN OUT b) IS
    VAR BYTE temp = a
    a = b
    b = temp
END PROCEDURE

Generated by JAL Syntax Documentation System | Source: DITA


Sub-programs: Procedures and Functions - JAL Language Syntax Reference

Sub-programs: Procedures and Functions JALV2 SYNTAX

Syntax

PROCEDURE identifier [ ’(’ [VOLATILE] type { IN | OUT | IN OUT } identifier 2 [’,’ ...] ’)’ IS

Description

statement_block END PROCEDURE FUNCTION identifier [ ’(’ [VOLATILE] type { IN | OUT | IN OUT } identifier 2 [’,’ ...] ’)’ RETURN type IS statement_block END FUNCTION The only difference between a PROCEDURE and a FUNCTION, is the former does not return a value, while the later does. The procedure identiﬁer exists in the block in which the procedure is deﬁned. A new block is immediately opened, and all parameters exist in that block. A parameter marked IN will be assigned the value passed when called. A parameter marked OUT will assign the resulting value to parameter passed when called. While in a sub-program, a new keyword is introduced: RETURN [ expr ] When executed, the sub program immediately returns. If the sub program is a FUNCTION, expr is required. If it is a PROCEDURE, expr is forbidden. A sub-program is executed simply by using its name. If parameters are speciﬁed in the sub-program deﬁnition, all parameters are required, otherwise none are allowed. A FUNCTION can be used anywhere a value is required (in expressions, as parameters to other sub-programs, etc). There is no limit to the number of parameters. JALv2 is a pass by value language. Conceptually, an IN parameter is read once when the sub-program enters, and an OUT parameter is written once when the sub-program returns. This is not always desired. For example if a sub-program writes a string of characters to the serial port (passed as parameter), only the last character written will be sent. For this case we need VOLATILE parameters. These are either read each time used (IN) or written each time assigned (OUT). This is accomplished using pseudo variables (see below). If the value passed is not a pseudo-variable, a suitable one is created. There are two ways to pass an array into a sub-program: PROCEDURE string_write (BYTE IN str[5]) IS... PROCEDURE string_write (BYTE IN str[]) IS... 23

Generated by JAL Syntax Documentation System | Source: DITA


RETURN - JAL Language Syntax Reference

RETURN JALV2 SYNTAX

Syntax

RETURN
[expr]

Description

Exits from a procedure or function. For functions, expr is required. For procedures, expr must not be specified.

Notes

Multiple RETURN statements can be used in a single subprogram.

Example

FUNCTION add(BYTE IN a, BYTE IN b) RETURN BYTE IS
    RETURN a + b
END FUNCTION

Generated by JAL Syntax Documentation System | Source: DITA


Pseudo-variables - JAL Language Syntax Reference

Pseudo-variables JALV2 SYNTAX

Syntax

procedure identifier'put(type in var) is
statement_block
end procedure
function identifier'get() return type is
statement_block
return expression
end function

Description

A pseudo-variable is a pair of sub-programs (GET and PUT) that work as if they are variables. If a If a If both a

Generated by JAL Syntax Documentation System | Source: DITA


ASSERT - JAL Language Syntax Reference

ASSERT JALV2 SYNTAX

Syntax

ASSERT expr

Description

This is only useful if the "-emu" compiler option has been used, otherwise it is ignored. If expr results in a zero value, the emulator will stop at this point.

Generated by JAL Syntax Documentation System | Source: DITA


INCLUDE - JAL Language Syntax Reference

INCLUDE JALV2 SYNTAX

Syntax

INCLUDE filename

Description

This instructs the compiler to stop parsing the current ﬁle, open and completely parse the include ﬁle, the return to this ﬁle on the next line. Note the included ﬁle must have an extension of ’.jal’ and the ﬁlename may not begin or end with a space.

Notes

included again. Also be aware the the ﬁlename is taken literally -- no transform is done on it. This should be taken into consideration if you are writing a library as some ﬁlesystems are case-sensitive, and others are not, so "MYLIBRARY" and "mylibrary" might be two different ﬁles.

Example

INCLUDE 16f877

Generated by JAL Syntax Documentation System | Source: DITA


FAST (Interrupts) - JAL Language Syntax Reference

FAST (Interrupts) JALV2 SYNTAX

Syntax

PRAGMA INTERRUPT FAST

Description

High-priority interrupt with minimal context switching.

Notes

Only on PICs with dual-priority interrupts.

Example

PROCEDURE high_isr IS
PRAGMA INTERRUPT FAST
    -- critical code
END PROCEDURE

Generated by JAL Syntax Documentation System | Source: DITA


Interrupts - JAL Language Syntax Reference

Interrupts JALV2 SYNTAX

Syntax

PROCEDURE identifier IS

Description

PRAGMA INTERRUPT [FAST] statement_block END PROCEDURE PRAGMA INTERRUPT tells JAL that this procedure can only be called by the microcontroller’s interrupt processing. Any number of procedures can be deﬁned as an interrupt handler. When an interrupt occurs, ﬁrst the microprocessor state is saved, then control passes to the ﬁrst procedure marked as an interrupt handler. Control continues to pass to each interrupt handler until the last, then the microprocessor state is restored and the interrupt ended. The programmer is responsible for clearing whatever bits caused the interrupt to happen. A procedure marked as an interrupt handler cannot be called directly from elsewhere in the program. Beyond that, an interrupt handler can do anything any other procedure can do. The order the interrupt handlers are called is undeﬁned, the only guarantee is each handler will be called at each interrupt, and will only be called once. If an interrupt handler executes a sub-program that is also executed by the main body of the program, that sub-program will be marked recursive and incur the recursion overhead each time it is called. If FAST is declared, the interrupt handler will only save the minimum amount of state necessary. This must be used with great care -- although the microprocessor state is saved, state used internally by the compiler is not. As such, only a completely assembly sub-program should be used. Any JAL statements might invalidate the internal state of the compiler. If any interrupt handler is marked FAST then only one interrupt handler is allowed. 26

Generated by JAL Syntax Documentation System | Source: DITA


TASK / START / SUSPEND - JAL Language Syntax Reference

TASK / START / SUSPEND JALV2 SYNTAX

Syntax

TASK identifier [(parameters)] IS
statement_block
END TASK

Description

Cooperative multitasking. Tasks started with START, yield with SUSPEND, end with RETURN.

Notes

Requires -task n option. Only one instance per task. Main program counts as a task.

Example

TASK blink IS
    FOREVER LOOP
        led = !led
        SUSPEND
    END LOOP
END TASK

Generated by JAL Syntax Documentation System | Source: DITA


usb_msd_tasks - JALlib Procedures Help

usb_msd_tasks JALLIB PROCEDURE

Signature

procedure usb_msd_tasks() is

Description

Poll USB MSD for tasks

Include

To use this procedure, include the library:

include usb_msd

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_msd_pata_hard_disk.jal

-- Title: USB Mass Storage Device Sample (pata hard disk)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program for USB MSD (Mass Storage Device) with pata hard disk.
--
--              Here are my speed tests:
--              Read Speed                               - 200KB/s
--              Write Speed                              - 180KB/s
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
-- http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
-- http://direction.scene-double.com/2008/07/08/usb-msd-bootloader-for-pic-microcontrollers.aspx
--
-- Notes:
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

include format

-- enable usb debugging
const bit USB_DEBUG = FALSE
const bit USB_DEBUG_HIGH = FALSE
;const bit USB_HID_DEBUG = TRUE
;const bit USB_HID_DEBUG_HIGH = TRUE

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = OFF    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_0 = ON  -- short debugging
debug_lvl_1 = OFF  -- display data in/out
debug_lvl_2 = OFF  -- display commands
debug_lvl_3 = OFF  -- short debug info
--
const byte debug_text0[] = "DEBUG STARTED"
debug_string(DEBUG_0,debug_text0)
debug_crlf(DEBUG_0)
--

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = TRUE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup MSD library
include usb_msd
usb_msd_init()
print_crlf(serial_data)
print_string(serial_data,"Your mass storage device size is ")
print_maxvar_dec(serial_data,byte*6(usb_msd_num_of_blocks)*512)
print_string(serial_data," bytes.")

--------------------------------------------------------------------------------
-- main Program
--------------------------------------------------------------------------------

-- define procedures and variables
procedure usb_disconnected_tasks()
procedure usb_connected_tasks()
var word char_count = 0
var word usb_check = 0
var byte usb_connected = TRUE

-- main loop to serve USB
forever loop
   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- Check if usb is still connected
   -- Another way would be to check the voltage on a USB+ pin.
   if USB_EVENT_OCCURRED == 1 then
      usb_check = 0
   elsif usb_check == 0xFFFF then
      -- USB is not connected
      usb_disconnected_tasks() -- perform your tasks
   else
      -- USB is connected
      usb_connected_tasks()    -- tasks while connected
      usb_check = usb_check + 1
   end if
end loop

-- Do anything you want here while usb is disconnected.
-- Quit the procedure when USB_EVENT_OCCURRED = 1
procedure usb_disconnected_tasks() is
   if usb_connected == TRUE then
      print_crlf(serial_data)
      print_string(serial_data, "USB is disconnected." )
      usb_connected = FALSE
   end if

   forever loop
      serial_data = "!"
      delay_1s(1)

      if USB_EVENT_OCCURRED == 1 then
         exit loop
      end if
   end loop
end procedure

-- Do anything you want here while usb is connected, but don't take long!
procedure usb_connected_tasks() is
   if usb_connected == FALSE then
      ;-- wait till MSD is configured
      usb_msd_wait_configured()
      print_crlf(serial_data)
      print_string(serial_data, "USB is connected." )
      usb_connected = TRUE
   end if

   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- let us know the PIC is actually doing something
   -- by sending char "." to serial port
   if char_count == 40000 then
      serial_data = "."
      _usec_delay(100)
      char_count = 0
   end if
   char_count = char_count + 1
end procedure

Generated by JALlib CHM Help System | Source: usb_msd.jal


PRAGMA KEEP - JAL Language Syntax Reference

PRAGMA KEEP JALV2 SYNTAX

Syntax

PRAGMA KEEP PAGE
PRAGMA KEEP BANK

Description

Forces always generating page/bank bit code.

Notes

Affects entire subprogram.

Example

PRAGMA KEEP BANK

Generated by JAL Syntax Documentation System | Source: DITA


PRAGMA TARGET - JAL Language Syntax Reference

PRAGMA TARGET JALV2 SYNTAX

Syntax

PRAGMA TARGET CLOCK frequency

Description

Sets processor clock frequency in Hz.

Notes

Required for _usec_delay and timing operations.

Example

PRAGMA TARGET CLOCK 20_000_000

Generated by JAL Syntax Documentation System | Source: DITA


Compiler Options - JAL Language Syntax Reference

Compiler Options JALV2 SYNTAX

Syntax

-debug -fastmath -task n -emu -s path

Description

Compiler flags: -debug (messages), -fastmath (optimize math), -task n (concurrent tasks), -emu (emulator), -s (lib path).

Notes

Options affect code generation and features.

Example

jalv2 -s lib program.jal
jalv2 -task 3 -fastmath program.jal

Generated by JAL Syntax Documentation System | Source: DITA


_DEBUG - JAL Language Syntax Reference

_DEBUG JALV2 SYNTAX

Syntax

_DEBUG "..."

Description

Generates a debug message that will only be displayed if the -debug compiler option is used.

Notes

Useful for conditional debug output during development.

Example

_DEBUG "this file is being deprecated"

Generated by JAL Syntax Documentation System | Source: DITA


hcsr04_measurement_error - JALlib Procedures Help

hcsr04_measurement_error JALLIB FUNCTION

Signature

function hcsr04_measurement_error() return bit is

Description

Returns TRUE when a distance measurement error was encountered. This error
occurs when the measured time is too long. This can occur when the object.
is out of reach or the module is not connected.

Include

To use this procedure, include the library:

include hcsr04

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_hcsr04_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the HC-SR04 Ultrasonic Ranging Module
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the HC-SR04
--              Ultra Sonic Ranging Module.
--              The LED bar is used to show the distance measured. The closed
--              to the module the more LEDs will be turned on.
--              The HC-SR04 library uses timer 1 to measure the distance.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Settings for the HCSR04 Ultrasonic Ranging Motule. The library uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a 1 MHz clock cannot be obtained the user must use HCSR04_SCALING.
--       For more information see the hcsr04 library.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the HCSR04 library will use the external interrupt (default), otherwise
-- it wil use the IOC interrupt.
-- const IOC_VERSION = TRUE -- When commented out using the IOC interrupt.
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias hcsr04_ioc_flag is IOCAF_IOCAF5
   -- Interrupt using IOC.
   alias hcsr04_echo_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interrupt using INT.
   alias hcsr04_echo_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Control pin for the module to start an echo.
alias hcsr04_trigger_pin is pin_a4 -- Pin 3 for 14 pin DIP
alias hcsr04_trigger_pin_direction is pin_a4_direction

-- Now we can include the library.
include hcsr04
hcsr04_init

-- Define the LED bar, we use port C (C0 .. C5).
alias led_bar is portc
portc_direction = OUTPUT

-- Some distance constants in mm
const dword MIN_DISTANCE = 20    -- 2 cm
const dword MAX_DISTANCE = 4_000 -- 400 cm
-- We have 6 LEDs and we only indicate a distance up to 30 cm
-- so 5 cm of 50 mm per LED.
const word MM_PER_LED = 50

-- Variables.
var word distance
var bit measurement_busy

measurement_busy = FALSE
led_bar = 0b0011_1111
_usec_delay(1_000_000)
led_bar = 0x00

forever  loop

   -- Start a measurement and wait for the result.
   if !measurement_busy then
      hcsr04_start_measurement()
      measurement_busy= TRUE
   end if

   if hcsr04_measurement_done() then
      --Get distance in in mm.
      distance = word(hcsr04_get_distance_mm() - MIN_DISTANCE)

      -- Create a LED bar based on the distance. The shorter the
      -- distance the more LEDs will be turned on.
      if (distance > (6 * MM_PER_LED)) then
         led_bar = 0b0011_1111
      elsif (distance > (5 * MM_PER_LED)) then
         led_bar = 0b0001_1111
      elsif (distance > (4 * MM_PER_LED)) then
         led_bar = 0b0000_1111
      elsif (distance > (3 * MM_PER_LED)) then
         led_bar = 0b0000_0111
      elsif (distance > (2 * MM_PER_LED)) then
         led_bar = 0b0000_0011
      elsif (distance > MM_PER_LED) then
         led_bar = 0b0000_0001
      else
         led_bar = 0b0000_0000
      end if
      measurement_busy = FALSE
   elsif hcsr04_measurement_error() then
      -- Blink the whole LED bar.
      for 5 loop
         led_bar = 0b0011_1111
         _usec_delay(500_000)
         led_bar = OFF
         _usec_delay(500_000)
      end loop
      measurement_busy = FALSE
   end if

   _usec_delay(100_000)

end loop

Generated by JALlib CHM Help System | Source: hcsr04.jal


ina3221_set_warning_alert_limit - JALlib Procedures Help

ina3221_set_warning_alert_limit JALLIB PROCEDURE

Signature

procedure ina3221_set_warning_alert_limit(byte in channel, sdword in limit) is

Description

Set the warning alert limit of the shunt voltage for the given channel.
Channel in range 0..2. Limit is in uV.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • channel - byte in
  • limit - sdword in

Return Value

None

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ASM / ASSEMBLER - JAL Language Syntax Reference

ASM / ASSEMBLER JALV2 SYNTAX

Syntax

ASM instruction

Description

Allows inline assembly code.

Notes

Use only when JAL features insufficient or speed critical.

Example

ASM nop

Generated by JAL Syntax Documentation System | Source: DITA


BANK / PAGE - JAL Language Syntax Reference

BANK / PAGE JALV2 SYNTAX

Syntax

BANK opcode
BANK file_register
PAGE opcode
PAGE label

Description

Ensures correct bank/page bits for assembly.

Notes

Only generated when necessary unless PRAGMA KEEP used.

Example

BANK movwf PORTA
PAGE goto my_label

Generated by JAL Syntax Documentation System | Source: DITA


LOCAL (Labels) - JAL Language Syntax Reference

LOCAL (Labels) JALV2 SYNTAX

Syntax

LOCAL
identifier
[, identifier2...]

Description

Declares assembly labels.

Notes

For use in CALL/GOTO within ASSEMBLER blocks.

Example

LOCAL loop_start
loop_start:
    decfsz counter, f
    goto loop_start

Generated by JAL Syntax Documentation System | Source: DITA


Assembly Op-codes - JAL Language Syntax Reference

Assembly Op-codes JALV2 SYNTAX

Syntax

addwf, andwf, clrf, clrw, comf, decf, decfsz, incf, incfsz, iorwf, movf, movwf, nop, rlf, rlcf, rlncf, rrf, rrcf, rrncf, subwf, swapf, xorwf, bcf, bsf, btfsc, btfss, addlw, andlw, call, clrwdt, goto, iorlw, movlw, retfie, retlw, return, sleep, sublw, xorlw, tblrd, tblwt, reset, option, tris

Description

Available PIC assembly opcodes. b=bit (0-7), d=destination ('f'/'w'), f=file register, n=literal (0-255), k=label/constant. Not all opcodes available on all devices.

Notes

Check device datasheet for complete opcode descriptions.

Example

ASM movlw 0x55
ASM movwf PORTA
ASM nop

Generated by JAL Syntax Documentation System | Source: DITA


Assembly Macros - JAL Language Syntax Reference

Assembly Macros JALV2 SYNTAX

Syntax

addcf, adddcf, b, bc, bdc, bnc, bndc, bnz, bz, clrc, clrdc, clrz, lcall, lgoto, movfw, negf, setc, setdc, setz, skpc, skpdc, skpnc, skpndc, skpnz, skpz, subcf, subdcf, tstf

Description

Common assembly macros that expand to one or more opcodes.

Notes

Macros improve readability and portability.

Example

ASM clrc  -- clear carry
ASM setc  -- set carry
ASM tstf temp

Generated by JAL Syntax Documentation System | Source: DITA


Data Directives (db/dw/ds) - JAL Language Syntax Reference

Data Directives (db/dw/ds) JALV2 SYNTAX

Syntax

db list  -- bytes
dw list  -- words
ds list  -- packed 7-bit

Description

Insert data into code area. db=bytes (one per word), dw=words (14-bit on 12/14-bit cores, 16-bit on 16-bit), ds=packed 7-bit values (two per word).

Notes

Data in program memory. Retrieval is chip-specific.

Example

ASSEMBLER
    db 0x12, 0x34, 0x56
    dw 0x1234, 0x5678
END ASSEMBLER

Generated by JAL Syntax Documentation System | Source: DITA


Multiplication / Division - JAL Language Syntax Reference

Multiplication / Division JALV2 SYNTAX

Syntax

* (multiply)
/ (divide)
% (modulus)

Description

Built-in math functions requiring one stack entry. Optimized for power-of-2 operations.

Notes

Function calls, expensive in code size. Use shifts for powers of 2.

Example

result = 10 * 20
quotient = 100 / 5
remainder = 17 % 5

Generated by JAL Syntax Documentation System | Source: DITA


Floating Point - JAL Language Syntax Reference

Floating Point JALV2 SYNTAX

Syntax

FLOAT type
Operations: +, -, *, /, comparisons

Description

Floating point via function calls (1-2 stack entries).

Notes

Never compare floats for equality. Use threshold: abs((A-B)/B) < 1e-6. Precision 6-9 digits.

Example

VAR FLOAT temp = 98.6
VAR FLOAT celsius = (temp - 32.0) * 5.0 / 9.0

Generated by JAL Syntax Documentation System | Source: DITA


_usec_delay - JAL Language Syntax Reference

_usec_delay JALV2 SYNTAX

Syntax

_usec_delay(cexpr)

Description

Exact microsecond delay using loops and no-ops.

Notes

Requires PRAGMA TARGET CLOCK. Interrupts must be disabled. Best for short delays.

Example

PRAGMA TARGET CLOCK 20_000_000
_usec_delay(100)  -- 100 us delay

Generated by JAL Syntax Documentation System | Source: DITA


SHARED (keyword) - JAL Language Syntax Reference

SHARED (keyword) JALV2 SYNTAX

Syntax

VAR [ VOLATILE ] [ SHARED ] type [ '*' cexpr ] identifier
    [ '[' [ cexpr ] ']' ]                    -- Array dimension
    [ { AT cexpr [ ':' bit ]
      | var [ ':' bit ]
      | '{' cexpr1 [ ',' cexpr2 ... ] '}'
      | IS var
      } ]                                    -- Placement
    [ '=' { cexpr
          | '{' cexpr1 [ ',' ... ] '}'
          | '"' ... '"'
          } ]                                -- Initialization
    [ ',' identifier ... ]                   -- Multiple variables

Description

Variable in shared memory (all banks). No bank bit setting needed.

Notes

Optimizes by eliminating bank switching.

Example

VAR SHARED BYTE global_counter

Generated by JAL Syntax Documentation System | Source: DITA


VOLATILE (keyword) - JAL Language Syntax Reference

VOLATILE (keyword) JALV2 SYNTAX

Syntax

VAR [ VOLATILE ] [ SHARED ] type [ '*' cexpr ] identifier
    [ '[' [ cexpr ] ']' ]                    -- Array dimension
    [ { AT cexpr [ ':' bit ]
      | var [ ':' bit ]
      | '{' cexpr1 [ ',' cexpr2 ... ] '}'
      | IS var
      } ]                                    -- Placement
    [ '=' { cexpr
          | '{' cexpr1 [ ',' ... ] '}'
          | '"' ... '"'
          } ]                                -- Initialization
    [ ',' identifier ... ]                   -- Multiple variables

Description

Prevents optimization. Variables read/written only once per expression.

Notes

Essential for interrupt-shared variables and hardware registers.

Example

VAR VOLATILE BYTE interrupt_flag

Generated by JAL Syntax Documentation System | Source: DITA


AT (Placement) - JAL Language Syntax Reference

AT (Placement) JALV2 SYNTAX

Syntax

VAR [ VOLATILE ] [ SHARED ] type [ '*' cexpr ] identifier
    [ '[' [ cexpr ] ']' ]                    -- Array dimension
    [ { AT cexpr [ ':' bit ]
      | var [ ':' bit ]
      | '{' cexpr1 [ ',' cexpr2 ... ] '}'
      | IS var
      } ]                                    -- Placement
    [ '=' { cexpr
          | '{' cexpr1 [ ',' ... ] '}'
          | '"' ... '"'
          } ]                                -- Initialization
    [ ',' identifier ... ]                   -- Multiple variables

Description

Places variable at specific memory location. Multiple addresses for mirrored registers.

Notes

For hardware registers or absolute addressing.

Example

VAR BYTE status AT 0x20
VAR BIT flag AT 0x03:0
VAR BYTE timer AT {0x01, 0x81}

Generated by JAL Syntax Documentation System | Source: DITA


JALlib Help

Statistics

Total Procedures: 0

Total Libraries: 278

Total JALv2 Syntax: 90

Mode: Sample-Filtered (Used in Samples)

Version: 3.58

Generated: 2025-11-06 22:17:19

JALLIB Libraries

accelerometer_gyroscope_bmi160 LIBRARY
adc LIBRARY
adc_hardware LIBRARY
arp LIBRARY
as5600l LIBRARY
beep LIBRARY
big_calendar LIBRARY
bit_array_1 LIBRARY
bluetooth_hc05 LIBRARY
bluetooth_hc06 LIBRARY
bmp085 LIBRARY
bmp180 LIBRARY
calendar LIBRARY
can_adapter LIBRARY
can_ascii LIBRARY
can_bicolor_leds LIBRARY
can_legacy LIBRARY
can_mcp2515 LIBRARY
canopen LIBRARY
characters LIBRARY
charlie LIBRARY
checksum LIBRARY
chipdef_jallib LIBRARY
co2_t6603 LIBRARY
co2_t6613_i2c LIBRARY
constants_jallib LIBRARY
crc16_ccitt_bitwise LIBRARY
crc16_ccitt_lookup LIBRARY
crc7_sd_card LIBRARY
dac_mcp4922 LIBRARY
dcf77_decoder LIBRARY
dds_ad9833 LIBRARY
dds_ad9850 LIBRARY
debounce LIBRARY
debug LIBRARY
debug_queue LIBRARY
delay LIBRARY
dfplayer LIBRARY
digital_potentiometer_mcp4131 LIBRARY
digital_potentiometer_x9c10x LIBRARY
ds18b20 LIBRARY
dtmf_encoder_ht9200 LIBRARY
ee_25aa02e48 LIBRARY
eeprom_24lc02 LIBRARY
eeprom_24lc256 LIBRARY
enc28j60 LIBRARY
esp8266 LIBRARY
ethernet_mac LIBRARY
fat32 LIBRARY
fat32_small LIBRARY
flash_data LIBRARY
flash_sst25vf LIBRARY
format LIBRARY
glcd_12x16_font LIBRARY
glcd_14x30_font LIBRARY
glcd_16x32_font LIBRARY
glcd_4x6_font LIBRARY
glcd_5x12_font LIBRARY
glcd_5x7_font LIBRARY
glcd_5x8_font LIBRARY
glcd_6x10_font LIBRARY
glcd_6x8_font LIBRARY
glcd_6x8_u_font LIBRARY
glcd_7x12_font LIBRARY
glcd_7x12_u_font LIBRARY
glcd_8x12_font LIBRARY
glcd_8x12_u_font LIBRARY
glcd_8x14_font LIBRARY
glcd_8x8_font LIBRARY
glcd_9x16_font LIBRARY
glcd_common LIBRARY
glcd_digits LIBRARY
glcd_font LIBRARY
glcd_ili9341 LIBRARY
glcd_ks0108 LIBRARY
glcd_nokia_5110 LIBRARY
glcd_ssd1306 LIBRARY
glcd_t6963 LIBRARY
glcd_touch_ads7843 LIBRARY
goel370 LIBRARY
gps_neo_6m LIBRARY
hcsr04 LIBRARY
http LIBRARY
humidity_sht LIBRARY
i2c_hardware LIBRARY
i2c_hardware2 LIBRARY
i2c_hw_slave LIBRARY
i2c_hw_slave_isr LIBRARY
i2c_hw_slave_msg LIBRARY
i2c_level1 LIBRARY
i2c_reset_bus LIBRARY
i2c_software LIBRARY
icmp LIBRARY
ina3221 LIBRARY
interrupt_on_change LIBRARY
ip_header LIBRARY
ir_ranger_gp2d02 LIBRARY
jascii LIBRARY
keyboard LIBRARY
large_array_1 LIBRARY
large_array_2 LIBRARY
large_array_3 LIBRARY
large_array_4 LIBRARY
large_array_5 LIBRARY
large_array_6 LIBRARY
lcd_backlight LIBRARY
lcd_dog_m_4 LIBRARY
lcd_dog_m_8 LIBRARY
lcd_dog_m_spi LIBRARY
lcd_dsm0822a LIBRARY
lcd_hd44780_4 LIBRARY
lcd_hd44780_8 LIBRARY
lcd_hd44780_common LIBRARY
lcd_hd44780_pcf8574 LIBRARY
lcd_hd44780_serial_sw LIBRARY
lcd_one_dot_matrix LIBRARY
lcd_sterm_master LIBRARY
lolfont LIBRARY
lolfont1 LIBRARY
ltc2942 LIBRARY
math LIBRARY
max7219_1 LIBRARY
max7219_7 LIBRARY
max7219_common LIBRARY
max7219_font LIBRARY
max7219_n LIBRARY
mcp23008 LIBRARY
mcp23s08 LIBRARY
mcp3424 LIBRARY
mcp9800 LIBRARY
memory_pointer0 LIBRARY
memory_pointer1 LIBRARY
memory_pointer2 LIBRARY
minixfs LIBRARY
minixfs_cmd LIBRARY
mp3_decoder_sta015 LIBRARY
mp3_decoder_vs1053b LIBRARY
nec_rc_decoder LIBRARY
networking LIBRARY
now LIBRARY
nrf24l01 LIBRARY
nrf905 LIBRARY
one_wire LIBRARY
pata_hard_disk LIBRARY
pca9685 LIBRARY
period_skip LIBRARY
philips_rc_decoder LIBRARY
pic_data_eeprom LIBRARY
pic_data_hef LIBRARY
pintools LIBRARY
pll_mc145156 LIBRARY
pps LIBRARY
print LIBRARY
profiler LIBRARY
ps2 LIBRARY
pwm_ccp1 LIBRARY
pwm_ccp10 LIBRARY
pwm_ccp2 LIBRARY
pwm_ccp3 LIBRARY
pwm_ccp4 LIBRARY
pwm_ccp5 LIBRARY
pwm_ccp6 LIBRARY
pwm_ccp7 LIBRARY
pwm_ccp8 LIBRARY
pwm_ccp9 LIBRARY
pwm_common LIBRARY
pwm_hardware LIBRARY
pwm_pwm1 LIBRARY
pwm_pwm10 LIBRARY
pwm_pwm11 LIBRARY
pwm_pwm12 LIBRARY
pwm_pwm2 LIBRARY
pwm_pwm3 LIBRARY
pwm_pwm4 LIBRARY
pwm_pwm5 LIBRARY
pwm_pwm6 LIBRARY
pwm_pwm7 LIBRARY
pwm_pwm8 LIBRARY
pwm_pwm9 LIBRARY
quadrature_counter_ls7366r LIBRARY
queue01 LIBRARY
queue02 LIBRARY
queue03 LIBRARY
queue04 LIBRARY
queue05 LIBRARY
queue06 LIBRARY
queue07 LIBRARY
queue08 LIBRARY
random LIBRARY
rda5807m LIBRARY
reboot LIBRARY
rtc_common LIBRARY
rtc_ds1302 LIBRARY
rtc_ds1307 LIBRARY
rtc_ds3231 LIBRARY
rtc_isr_tmr0 LIBRARY
rtc_isr_tmr1 LIBRARY
rtc_isr_tmr2 LIBRARY
rtc_isr_tmr3 LIBRARY
rtc_mcp7940 LIBRARY
rtc_pcf8563 LIBRARY
rtcc_hw LIBRARY
sd_card LIBRARY
sdp600 LIBRARY
serial_hardware LIBRARY
serial_hardware2 LIBRARY
serial_hardware3 LIBRARY
serial_hw2_int_cts LIBRARY
serial_hw3_int_cts LIBRARY
serial_hw_int_cts LIBRARY
serial_software LIBRARY
servo_rc_master LIBRARY
servo_rc_master_dedicated LIBRARY
servo_rc_slave LIBRARY
seven_segment LIBRARY
seven_segment_multiplexer LIBRARY
shift_register_74595 LIBRARY
si5351a LIBRARY
sirc LIBRARY
sirc_rx LIBRARY
sirc_tx LIBRARY
slip LIBRARY
smbus_mlx90615 LIBRARY
spi_common LIBRARY
spi_host_hw LIBRARY
spi_host_hw2 LIBRARY
spi_master_hw LIBRARY
spi_master_hw2 LIBRARY
spi_master_sw LIBRARY
spi_slave_hw LIBRARY
sram_23k256 LIBRARY
stepper_unipolar_blocking LIBRARY
stepper_unipolar_common LIBRARY
stepper_unipolar_nonblocking LIBRARY
steppermotor LIBRARY
stopwatch LIBRARY
stopwatch2 LIBRARY
storage_drivers LIBRARY
strings LIBRARY
tcp LIBRARY
temperature_humidity_dht11 LIBRARY
temperature_max6675 LIBRARY
temperature_sht LIBRARY
temperature_tc77 LIBRARY
timer0 LIBRARY
timer0_isr_interval LIBRARY
timer0_poll_interval LIBRARY
timer1 LIBRARY
timer3 LIBRARY
timer_frequency LIBRARY
tm1637 LIBRARY
tm1638 LIBRARY
tm1638_font LIBRARY
tm1640 LIBRARY
transceiver_cc1101 LIBRARY
udp LIBRARY
unittest LIBRARY
usart2_common LIBRARY
usart3_common LIBRARY
usart_common LIBRARY
usb_defs LIBRARY
usb_drv LIBRARY
usb_drv_cdc_class LIBRARY
usb_drv_core LIBRARY
usb_keyboard LIBRARY
usb_mouse LIBRARY
usb_msd LIBRARY
usb_serial LIBRARY
virtual_wire LIBRARY
virtual_wire_receiver LIBRARY
virtual_wire_transmitter LIBRARY
vl53l0x LIBRARY
ws2812b_async LIBRARY
ws2812b_common LIBRARY
ws2812b_spi LIBRARY
ws2812b_sw LIBRARY
ws2812b_sync LIBRARY
xbee_api LIBRARY

JALv2 Syntax

Debug JALV2 SYNTAX
Error JALV2 SYNTAX
Usec Delay JALV2 SYNTAX
Warn JALV2 SYNTAX
Adc Off JALV2 SYNTAX
Alias JALV2 SYNTAX
Aliases JALV2 SYNTAX
Analog Off JALV2 SYNTAX
Arrays JALV2 SYNTAX
Ascii Escape Sequences JALV2 SYNTAX
Asm Assembler JALV2 SYNTAX
Assembly JALV2 SYNTAX
Assembly Macros JALV2 SYNTAX
Assembly Op-Codes JALV2 SYNTAX
Assert JALV2 SYNTAX
At Placement JALV2 SYNTAX
Available Opcodes JALV2 SYNTAX
Bank Page JALV2 SYNTAX
Block JALV2 SYNTAX
Built In Functions JALV2 SYNTAX
Case JALV2 SYNTAX
Casting JALV2 SYNTAX
Comments JALV2 SYNTAX
Common Macros JALV2 SYNTAX
Compiler Options JALV2 SYNTAX
Const Constants JALV2 SYNTAX
Constant Arrays JALV2 SYNTAX
Constants JALV2 SYNTAX
Count JALV2 SYNTAX
Data Directives JALV2 SYNTAX
Data Directives Dbdwds JALV2 SYNTAX
Defined JALV2 SYNTAX
Elsif Else JALV2 SYNTAX
Exit Loop JALV2 SYNTAX
Expressions JALV2 SYNTAX
Fast Interrupts JALV2 SYNTAX
Flash Erase Block JALV2 SYNTAX
Floating Point JALV2 SYNTAX
Floating Point Operations JALV2 SYNTAX
Flow Control JALV2 SYNTAX
For JALV2 SYNTAX
Forever JALV2 SYNTAX
I2C Hw Slave On Error JALV2 SYNTAX
Identifiers JALV2 SYNTAX
If JALV2 SYNTAX
In Out In Out JALV2 SYNTAX
Include JALV2 SYNTAX
Interrupts JALV2 SYNTAX
Local Labels JALV2 SYNTAX
Loop JALV2 SYNTAX
Message Generating JALV2 SYNTAX
Minix Dev Print Super Block JALV2 SYNTAX
Multiplication Division JALV2 SYNTAX
Mutiplication Division Modulus JALV2 SYNTAX
Named Constants JALV2 SYNTAX
Numeric Separators JALV2 SYNTAX
Operator Precedence JALV2 SYNTAX
Operators JALV2 SYNTAX
Operators Casting Expressions JALV2 SYNTAX
Other Keywords JALV2 SYNTAX
Otherwise JALV2 SYNTAX
Pragma JALV2 SYNTAX
Pragma Keep JALV2 SYNTAX
Pragma Target JALV2 SYNTAX
Procedures Functions JALV2 SYNTAX
Promotion Rules JALV2 SYNTAX
Pseudo-Variables JALV2 SYNTAX
Pseudo Variables JALV2 SYNTAX
Record Structures JALV2 SYNTAX
Records JALV2 SYNTAX
Repeat JALV2 SYNTAX
Return JALV2 SYNTAX
Scope JALV2 SYNTAX
Shared Keyword JALV2 SYNTAX
String Literals JALV2 SYNTAX
Sub-Programs Procedures And JALV2 SYNTAX
Task Start Suspend JALV2 SYNTAX
Tasks JALV2 SYNTAX
Types JALV2 SYNTAX
Unnamed Constants JALV2 SYNTAX
Until JALV2 SYNTAX
Usb Disconnected Tasks JALV2 SYNTAX
Usb Tasks JALV2 SYNTAX
Using In For JALV2 SYNTAX
Var Variables JALV2 SYNTAX
Variables JALV2 SYNTAX
Variables Constants Aliases JALV2 SYNTAX
Volatile Keyword JALV2 SYNTAX
Whereis JALV2 SYNTAX
While JALV2 SYNTAX


ISR - JALlib Procedures Help

ISR JALLIB PROCEDURE

Signature

procedure ISR() is

Description

No description available.

Include

To use this procedure, include the library:

include timer0_isr_interval

Parameters

None

Return Value

None

Example

From sample file: 16f1455_tutorial_usb_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Tutorial USB Serial Demo
-- Author: Rob Jansen, Copyright (c) 2022..2024, all rights reserved.
-- Adapted-by: Rob Hamerling, Rob Jansen
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This application demonstrates the functionality of the USB Serial library,
--              this application will emulate a RS-232 terminal device. Once the USB device
--              has been detected by the host operating system, it will create a virtual
--              serial (COM) port. When opening this port on the host computer using a
--              standard terminal application 2 LEDs can remotely be controlled.
--              The status of the LEDs is returned to the host.-
--
--
-- Notes: For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
--        the USB connection and the PIC16F1455 is connected as follows:
--        *) USB data- wire to pin 12 (A1 / D-)
--        *) USB data+ wire to pin 13 (A0 / D+)
--        *) USB power wire to pin 1 (VDD). Don't forget a 100nF decoupling capacitor.
--        *) USB ground wire to pin 14 (VSS or GND)
--        *) A resistor of 33kOhm to pin 4 (MCLR) and VDD. We use internal reset.
--        *) A capacitor of 470nF to pin 11 (Vusb3v3) and GND.
--        *) A Yellow LED with 330 Ohm resistor to pin 8 (C2).
--           (indicates that USB is configured.)
--        *) A Red LED with 330 Ohm resistor to pin 6 (C4).
--        *) A Green LED with 330 Ohm resistor to pin 7 (C3).
--
--        For In Circuit Serial Programming:
--        *) ICSPDAT wire to pin 10 (C0)
--        *) ICSPCLK wire to pin 9 (C1)
--
include 16f1455             -- Target processor.

pragma target clock         48_000_000

-- Settings for internal clock and system clock 48 MHz.
pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses.
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- External reset
pragma target LVP           ENABLED  -- allow low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a and and set port c to output just to
-- have no floating input pins.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1111          -- Weak-pull up for all inputs.
TRISC         = 0b0000_0000          -- Port c output.

-- Include serial library and print library for formatting print output.
include usb_serial
include print

-- Aliases for LEDs, active HIGH.
alias led_red is pin_C4
pin_C4_direction = output            -- Pin 6 of 14 pin DIP.
alias led_green is pin_C3
pin_C3_direction = output            -- Pin 7 of 14 pin DIP.
alias led_yellow is pin_C2
pin_C2_direction = output            -- Pin 8 of 14 pin DIP.

-- Variables.
var byte character
var bit red_value, green_value

-- ------------- The main program starts here  ------------------------

-- Setup the USB serial library.
usb_serial_init()

-- LEDs off.
led_yellow = FALSE
red_value = FALSE
green_value = FALSE

forever loop

   -- Update Red and Green LEDs.
   led_red = red_value
   led_green = green_value

   -- Poll the usb ISR function on a regular base,
   -- in order to serve the USB requests
   usb_serial_flush()

   -- Check if USB device has been configured by the host.
   if ( usb_cdc_line_status() !=  0x00 )  then
      led_yellow = TRUE
   else
      led_yellow = FALSE    -- disconnected
      red_value = FALSE     -- red led off
      green_value = FALSE   -- green led off
   end if

   -- Check for input character. If OK, toggle led value and report to host.
   if usb_serial_read(character) then
      if (character == "R") | (character == "r") then
         red_value = !red_value
         print_string(usb_serial_data, "Red LED is ")
         if red_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      elsif (character == "G") | (character == "g") then
         green_value = !green_value
         print_string(usb_serial_data, "Green LED is ")
         if green_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      else
         print_string(usb_serial_data, "Expecting 'r' or 'g'")
      end if
      print_crlf(usb_serial_data)
   end if

end loop
--

Generated by JALlib CHM Help System | Source: timer0_isr_interval.jal


RTC - JALlib Procedures Help

RTC JALLIB PROCEDURE

Signature

procedure RTC() is

Description

No description available.

Include

To use this procedure, include the library:

include rtc_isr_tmr3

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: rtc_isr_tmr3.jal


_fat32_read_dir_info - JALlib Procedures Help

_fat32_read_dir_info JALLIB PROCEDURE

Signature

procedure _fat32_read_dir_info() is

Description

Reads where file names in the current dir are stored, and stores them
into fat32_entry_location[]

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_usb_msd_sd_card.jal

-- Title: USB Mass Storage Device Sample + FAT32 (SD Card)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Fat32 + USB MSD.
--              Acts as a mass storage device when USB is plugged in.
--              Can read/write via FAT32 lib when USB is not plugged in.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
-- http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
-- http://direction.scene-double.com/2008/07/08/usb-msd-bootloader-for-pic-microcontrollers.aspx
--
-- Notes:
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- print library
const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

include format

-- enable usb debugging
const bit USB_DEBUG = FALSE
const bit USB_DEBUG_HIGH = FALSE
;const bit USB_HID_DEBUG = TRUE
;const bit USB_HID_DEBUG_HIGH = TRUE

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = OFF    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_0 = ON  -- short debugging
debug_lvl_1 = OFF  -- display data in/out
debug_lvl_2 = OFF  -- display commands
debug_lvl_3 = OFF  -- short debug info
--
const byte debug_text0[] = "DEBUG STARTED"
debug_string(DEBUG_0,debug_text0)
debug_crlf(DEBUG_0)
--

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_READ_EXTRA_SPEED = TRUE -- extra speed
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings
--
if sd_has_error == TRUE then
   const byte SD_HAS_ERROR_MESSAGE[] = "ERROR - SD CARD FAILED"
   print_string(serial_data, SD_HAS_ERROR_MESSAGE)
end if

-- setup MSD library
include usb_msd
usb_msd_init()
--
print_crlf(serial_data)
print_string(serial_data,"Your mass storage device size is ")
print_maxvar_dec(serial_data,byte*6(usb_msd_num_of_blocks)*512)
print_string(serial_data," bytes.")

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 100            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

--------------------------------------------------------------------------------
-- main Program
--------------------------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

--------------------------------------------------------------------------------
-- main loop
--------------------------------------------------------------------------------

-- define procedures and variables
procedure usb_disconnected_tasks()
procedure usb_connected_tasks()
var word char_count = 0
var word usb_check = 0
var byte usb_connected = TRUE

-- main loop to serve USB
forever loop
   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- Check if usb is still connected
   -- Another way would be to check the voltage on a USB+ pin.
   if USB_EVENT_OCCURRED == 1 then
      usb_check = 0
   elsif usb_check == 0xFFFF then
      -- USB is not connected
      usb_disconnected_tasks() -- perform your tasks
   else
      -- USB is connected
      usb_connected_tasks()
      usb_check = usb_check + 1
   end if
end loop

-- Do anything you want here while usb is disconnected.
-- Quit the procedure when USB_EVENT_OCCURRED = 1
procedure usb_disconnected_tasks() is
   if usb_connected == TRUE then
      print_crlf(serial_data)
      print_string(serial_data, "USB is disconnected." )
      usb_connected = FALSE
   end if

   ------------------------------------------------------------
   -- example fat32 user interaction,
   -- send file/dir number via serial port to go into it
   --
   -- if volume id selected, list the current dir (root dir)
   -- if directory selected go into it and list it
   -- if file selected go into file and read it
   ------------------------------------------------------------

   _fat32_read_dir_info() -- refresh the current dir
   fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   separator() -- send "-----" and go to next example
   var byte data
   var dword step1
   var word step2
   var byte file_number2 = 0
   forever loop
      separator() -- send "-----" then loop and wait for user input

      -- this is not needed serial_sw.
      -- serial_data_available doesn't exist on serial sw.
      if defined(serial_data_available) then
         while !serial_data_available loop
            if USB_EVENT_OCCURRED == 1 then
               exit loop
            end if
         end loop
      end if

      if USB_EVENT_OCCURRED == 1 then
         exit loop
      end if

      file_number2 = serial_data

      -- choose a file for reading or dir for opening
      if fat32_cd(file_number2) then             -- if change directory is successful
         fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
      elsif fat32_file_open(file_number2) then   -- if go into file is successful

         -- calculate number of sectors in file
         var dword sectors_available
         if (fat32_file_size) == (fat32_file_size / 512) * 512 then
            sectors_available = (fat32_file_size / 512)
         else
            sectors_available = (fat32_file_size / 512) + 1
         end if

         -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
         -- Read from any sector number in the file, in any order you wish.
   ;      for sectors_available using step1 loop
   ;
   ;         -- set the data to be written
   ;         for 512 using step2 loop
   ;            fat32_sector_buffer[step2] = "E"
   ;         end loop
   ;
   ;         -- write one sector to the disk
   ;         fat32_write_file_sector_number(step1)
   ;      end loop

         -- EXAMPLE 3 READ (fast and user friendly) from fat32 sample.
         -- Read from any sector number in the file, in any order you wish.
         for sectors_available using step1 loop
            -- read one sector from the disk
            fat32_read_file_sector_number(step1)
            -- send the sector via serial port
            for 512 using step2 loop
               serial_data = fat32_sector_buffer[step2]
            end loop

            if USB_EVENT_OCCURRED == 1 then
               exit loop
            end if
         end loop

         fat32_file_close()
      end if

      if USB_EVENT_OCCURRED == 1 then
         exit loop
      end if
   end loop

end procedure

-- Do anything you want here while usb is connected, but don't take long!
procedure usb_connected_tasks() is
   if usb_connected == FALSE then
      ;-- wait till MSD is configured
      usb_msd_wait_configured()
      print_crlf(serial_data)
      print_string(serial_data, "USB is connected." )
      usb_connected = TRUE
   end if

   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- let us know the PIC is actually doing something
   -- by sending char "." to serial port
   if char_count == 40000 then
      serial_data = "."
      _usec_delay(100)
      char_count = 0
   end if
   char_count = char_count + 1
end procedure

Generated by JALlib CHM Help System | Source: fat32.jal


_sd_read_512 - JALlib Procedures Help

_sd_read_512 JALLIB PROCEDURE

Signature

procedure _sd_read_512() is

Description

Read 512 bytes from SD card into sector buffer (optimized, no CRC)
High-speed unrolled loop for maximum read performance

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


_sd_read_512_crc - JALlib Procedures Help

_sd_read_512_crc JALLIB PROCEDURE

Signature

procedure _sd_read_512_crc() is

Description

Read 512 bytes from SD card into sector buffer with CRC validation
High-speed unrolled loop with CRC16 calculation per byte

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


_sd_write_512 - JALlib Procedures Help

_sd_write_512 JALLIB PROCEDURE

Signature

procedure _sd_write_512() is

Description

Write 512 bytes from sector buffer to SD card (optimized, no CRC)
High-speed unrolled loop for maximum write performance

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


_sd_write_512_crc - JALlib Procedures Help

_sd_write_512_crc JALLIB PROCEDURE

Signature

procedure _sd_write_512_crc() is

Description

Write 512 bytes from sector buffer to SD card with CRC calculation
High-speed unrolled loop with CRC16 calculation per byte

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


abs16 - JALlib Procedures Help

abs16 JALLIB FUNCTION

Signature

function abs16(sword in x) return word is

Description

Title: Obtain absolute value of a signed 16-bits integer
Arguments: signed 16-bits integer
Returns: unsigned 16-bits integer
Original: Eur van Andel

Include

To use this procedure, include the library:

include math

Parameters

  • x - sword in

Return Value

word - unsigned 16-bits integer Original: Eur van Andel

Example

From sample file: 18f2685_math.jal

-- Title: sample for math.jal, showing use of abs() and sign() functions
-- Author: Eur van Andel Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: shows 3 signed variables which can be incremented and decremented
-- and the result of the abs() and sign() functions on these variables.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

include 18f2685
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = 0b_0             -- no watchdog

enable_digital_io()              -- no analog functions used

-- pick one of the following LCD connections:

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20

var bit lcd_sterm_pin is pin_a0     -- Sterm LCD & keyboard \
var bit lcd_sterm_pin_dir is pin_a0_direction   --               >  single pin LCD & keyboard connection
include lcd_sterm_master      -- library for LCD and keyboard   /   this has PIC inside as well

-- alias LCD_RS           is pin_b5       -- LCD command/data select       \
-- alias LCD_EN           is pin_b4       -- LCD data trigger               \
-- alias LCD_dataport     is portb_low    -- LCD data nibble                 > traditional 6 pin LCD connection
-- portb_direction        = all_output    -- LCD data is portb_low          /
-- include lcd_hd44780_4                  -- LCD library with 4 data lines /
-- lcd_init()

include math                              -- duh
include print                             -- nice formatted output

var sbyte  x = 3
var sword  y = -3
var sdword z = 5

procedure keyboard() is

   if getkey() == 1 then  x = x + 1    end if  -- manual override
   if getkey() == 4 then  x = x - 1    end if

   if getkey() == 2 then  y = y + 1    end if
   if getkey() == 5 then  y = y -1     end if

   if getkey() == 3 then  z = z + 1    end if
   if getkey() == 6 then  z = z -1     end if

   if getkey() == 7 then         end if
   if getkey() == 0x0A then      end if

   if getkey() == 8 then      end if

   if getkey() == 0x0F then      end if
   if getkey() == 0x0E then      end if

   if getkey() == 9 then         end if
   if getkey() == 0x0D then      end if

   if getkey() == 0x0B then      end if
   if getkey() == 0 then         end if
   if getkey() == 0x0C then      end if

end procedure

-- START MAIN

delay_100ms(5)
lcd_clear_screen
delay_100ms(5)
lcd_clear_screen

--                 12345678901234567890
const byte str0[]="math demo sample    "  -- print banner
const byte str1[]="abs() and sign()    "
const byte str2[]="use keys 1..6       "

lcd_cursor_position(0,0)
print_string(lcd, str0)
lcd_cursor_position(1,0)
print_string(lcd, str1)

delay_1s(5)

lcd_clear_screen

forever loop

   lcd_cursor_position(0,0)
   lcd = "x" lcd = "="lcd = " "
   print_sbyte_dec(lcd, x)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_byte_dec(lcd, abs8(x))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign8(x))
   if x < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(1,0)
   lcd = "y" lcd = "="lcd = " "
   print_sword_dec(lcd, y)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_word_dec(lcd, abs16(y))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign16(y))
   if y < 10 & x > 0 then
      lcd = " "                  -- cleaning junk from LCD
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(2,0)
   lcd = "z" lcd = "="lcd = " "
   print_sdword_dec(lcd, z)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_dword_dec(lcd, abs32(z))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign32(z))
   lcd = " "
   if z < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(3,0)
   print_string(lcd, str2)

   delay_1ms(200)   -- proper LCD refresh rate

   keyboard()

end loop

Generated by JALlib CHM Help System | Source: math.jal


abs32 - JALlib Procedures Help

abs32 JALLIB FUNCTION

Signature

function abs32(sdword in x) return dword is

Description

Title: Obtain absolute value of a signed 32-bits integer
Arguments: signed 32-bits integer
Returns: unsigned 32-bits integer
Original: Eur van Andel

Include

To use this procedure, include the library:

include math

Parameters

  • x - sdword in

Return Value

None

Example

From sample file: 18f2685_math.jal

-- Title: sample for math.jal, showing use of abs() and sign() functions
-- Author: Eur van Andel Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: shows 3 signed variables which can be incremented and decremented
-- and the result of the abs() and sign() functions on these variables.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

include 18f2685
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = 0b_0             -- no watchdog

enable_digital_io()              -- no analog functions used

-- pick one of the following LCD connections:

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20

var bit lcd_sterm_pin is pin_a0     -- Sterm LCD & keyboard \
var bit lcd_sterm_pin_dir is pin_a0_direction   --               >  single pin LCD & keyboard connection
include lcd_sterm_master      -- library for LCD and keyboard   /   this has PIC inside as well

-- alias LCD_RS           is pin_b5       -- LCD command/data select       \
-- alias LCD_EN           is pin_b4       -- LCD data trigger               \
-- alias LCD_dataport     is portb_low    -- LCD data nibble                 > traditional 6 pin LCD connection
-- portb_direction        = all_output    -- LCD data is portb_low          /
-- include lcd_hd44780_4                  -- LCD library with 4 data lines /
-- lcd_init()

include math                              -- duh
include print                             -- nice formatted output

var sbyte  x = 3
var sword  y = -3
var sdword z = 5

procedure keyboard() is

   if getkey() == 1 then  x = x + 1    end if  -- manual override
   if getkey() == 4 then  x = x - 1    end if

   if getkey() == 2 then  y = y + 1    end if
   if getkey() == 5 then  y = y -1     end if

   if getkey() == 3 then  z = z + 1    end if
   if getkey() == 6 then  z = z -1     end if

   if getkey() == 7 then         end if
   if getkey() == 0x0A then      end if

   if getkey() == 8 then      end if

   if getkey() == 0x0F then      end if
   if getkey() == 0x0E then      end if

   if getkey() == 9 then         end if
   if getkey() == 0x0D then      end if

   if getkey() == 0x0B then      end if
   if getkey() == 0 then         end if
   if getkey() == 0x0C then      end if

end procedure

-- START MAIN

delay_100ms(5)
lcd_clear_screen
delay_100ms(5)
lcd_clear_screen

--                 12345678901234567890
const byte str0[]="math demo sample    "  -- print banner
const byte str1[]="abs() and sign()    "
const byte str2[]="use keys 1..6       "

lcd_cursor_position(0,0)
print_string(lcd, str0)
lcd_cursor_position(1,0)
print_string(lcd, str1)

delay_1s(5)

lcd_clear_screen

forever loop

   lcd_cursor_position(0,0)
   lcd = "x" lcd = "="lcd = " "
   print_sbyte_dec(lcd, x)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_byte_dec(lcd, abs8(x))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign8(x))
   if x < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(1,0)
   lcd = "y" lcd = "="lcd = " "
   print_sword_dec(lcd, y)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_word_dec(lcd, abs16(y))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign16(y))
   if y < 10 & x > 0 then
      lcd = " "                  -- cleaning junk from LCD
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(2,0)
   lcd = "z" lcd = "="lcd = " "
   print_sdword_dec(lcd, z)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_dword_dec(lcd, abs32(z))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign32(z))
   lcd = " "
   if z < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(3,0)
   print_string(lcd, str2)

   delay_1ms(200)   -- proper LCD refresh rate

   keyboard()

end loop

Generated by JALlib CHM Help System | Source: math.jal


abs8 - JALlib Procedures Help

abs8 JALLIB FUNCTION

Signature

function abs8(sbyte in x) return byte is

Description

Title: Obtain absolute value of a signed 8-bits integer
Arguments: signed 8-bits integer
Returns: unsigned 8-bits integer
Original: Eur van Andel

Include

To use this procedure, include the library:

include math

Parameters

  • x - sbyte in

Return Value

byte - unsigned 8-bits integer Original: Eur van Andel

Example

From sample file: 18f2685_math.jal

-- Title: sample for math.jal, showing use of abs() and sign() functions
-- Author: Eur van Andel Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: shows 3 signed variables which can be incremented and decremented
-- and the result of the abs() and sign() functions on these variables.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

include 18f2685
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = 0b_0             -- no watchdog

enable_digital_io()              -- no analog functions used

-- pick one of the following LCD connections:

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20

var bit lcd_sterm_pin is pin_a0     -- Sterm LCD & keyboard \
var bit lcd_sterm_pin_dir is pin_a0_direction   --               >  single pin LCD & keyboard connection
include lcd_sterm_master      -- library for LCD and keyboard   /   this has PIC inside as well

-- alias LCD_RS           is pin_b5       -- LCD command/data select       \
-- alias LCD_EN           is pin_b4       -- LCD data trigger               \
-- alias LCD_dataport     is portb_low    -- LCD data nibble                 > traditional 6 pin LCD connection
-- portb_direction        = all_output    -- LCD data is portb_low          /
-- include lcd_hd44780_4                  -- LCD library with 4 data lines /
-- lcd_init()

include math                              -- duh
include print                             -- nice formatted output

var sbyte  x = 3
var sword  y = -3
var sdword z = 5

procedure keyboard() is

   if getkey() == 1 then  x = x + 1    end if  -- manual override
   if getkey() == 4 then  x = x - 1    end if

   if getkey() == 2 then  y = y + 1    end if
   if getkey() == 5 then  y = y -1     end if

   if getkey() == 3 then  z = z + 1    end if
   if getkey() == 6 then  z = z -1     end if

   if getkey() == 7 then         end if
   if getkey() == 0x0A then      end if

   if getkey() == 8 then      end if

   if getkey() == 0x0F then      end if
   if getkey() == 0x0E then      end if

   if getkey() == 9 then         end if
   if getkey() == 0x0D then      end if

   if getkey() == 0x0B then      end if
   if getkey() == 0 then         end if
   if getkey() == 0x0C then      end if

end procedure

-- START MAIN

delay_100ms(5)
lcd_clear_screen
delay_100ms(5)
lcd_clear_screen

--                 12345678901234567890
const byte str0[]="math demo sample    "  -- print banner
const byte str1[]="abs() and sign()    "
const byte str2[]="use keys 1..6       "

lcd_cursor_position(0,0)
print_string(lcd, str0)
lcd_cursor_position(1,0)
print_string(lcd, str1)

delay_1s(5)

lcd_clear_screen

forever loop

   lcd_cursor_position(0,0)
   lcd = "x" lcd = "="lcd = " "
   print_sbyte_dec(lcd, x)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_byte_dec(lcd, abs8(x))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign8(x))
   if x < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(1,0)
   lcd = "y" lcd = "="lcd = " "
   print_sword_dec(lcd, y)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_word_dec(lcd, abs16(y))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign16(y))
   if y < 10 & x > 0 then
      lcd = " "                  -- cleaning junk from LCD
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(2,0)
   lcd = "z" lcd = "="lcd = " "
   print_sdword_dec(lcd, z)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_dword_dec(lcd, abs32(z))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign32(z))
   lcd = " "
   if z < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(3,0)
   print_string(lcd, str2)

   delay_1ms(200)   -- proper LCD refresh rate

   keyboard()

end loop

Generated by JALlib CHM Help System | Source: math.jal


adc.jal - JALLIB Library Documentation

adc.jal JALLIB LIBRARY

Title

ADC hardware, built-in PIC ADC module

Author

Stef Mientki, Copyright (c) 2002..2024, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to handle ADC peripheral, supporting low (8-bits) and high
(16-bits) resolution (whatever the PIC supports). Since the differences
between the various ADC features are too different for various PICs, this
library only provides some basic ADC features.
The user has to do the following in the main program using the datasheet
of the PIC that is being used:
1) Set the used ADC pin(s) as analog input
2) Set the refernce voltage for the ADC (default is often VDD)
3) Set the ADC clock according to the datasheet and the target clock
being used by the main program (FRC is safe to use)
For more information:
-) See http://justanotherlanguage.org/content/jallib/tutorials/tutorial_adc_intro
Some constants can be overruled by the main program:
- ADC_TEMP: Careful, computation related to temperature very approximative
- ADC_RSOURCE: Input resistance on ADC input channel
- ADC_MAX_TAD: Maximum conversion time.

Notes

This is a heavy refactoring/rewriting of original library of Stef Mientki.
Deprecated functions have been removed.
--------------------------------------------------------------------------------

By default ADC_RSOURCE is the maximum recommended value in the datasheets

Constants and Variables

ADC_RSOURCE - const word = 10_000 -- default: 10K
default: 10K
ADC_TEMP - const byte = 25 -- default: 25 degrees C
default: 25 degrees C

Routines

  • _adc_init_acquisition_delay - Procedure
  • _adc_read - Function returns word
  • adc_init - Procedure
  • adc_read_high_res - Function returns word
  • adc_read_low_res - Function returns byte


adc_hardware.jal - JALLIB Library Documentation

adc_hardware.jal JALLIB LIBRARY

Title

ADC hardware, built-in PIC ADC module

Author

Stef Mientki, Copyright (c) 2002..2008, all rights reserved., Adapted-by: Sebastien Lelong.

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library to use the PIC's AD converter
See 16F87x datasheet (DS30292C, p112)
Number of channels, behind "--" yields only for 16F874 and 16F877
No external Vref: Nchan = 1,3,5 -- 6,8
Only external +Vref: Nchan = 2,4 -- 5,7
Both external +Vref and - Vref: Nchan = 1,2,3 -- 4,6
--
Analog channels can still be used as digital outputs, by setting
pin = output
--
relevant IO pins
* RA0 = AN0
* RA1 = AN1
* RA2 = AN2 or -Vref
* RA3 = AN3 or +Vref
* RA4 = no analog IO
* RA5 = AN4
* next pins only for 16F874 and 16F877
* RE0 = AN5
* RE1 = AN6
* RE2 = AN7
--
--
Example PIC-AD
-- (if you use JALcc, you can copy the complete example below and "uncomment" it)
-- define the AD converter settings
const ADC_hardware_Nchan = 2 ;number of selected channels
const ADC_hardware_NVref = 0 ;number of external references
const ADC_hardware_Rsource = 10_000 ;maximum source resistance
const ADC_hardware_high_resolution = true ;true = high resolution = 10 bits
;false = low resolution = 8 bits
-- get the library, after defining the constants
include adc_hardware
--
-- initialize the AD converter according to the above parameters
ADC_init
--
-- now take a sample
-- read high resolution, channel 0
var_word=adc_read(0)
-- read low resolution, channel 0
var_byte=adc_read_low_res(0)
-- -----------------------------------------------------------------------------

Sources

I (Stef) mixed the following libraries with my own ideas
* f877_modules.jal from Javier Martinez
* janalog.jal from Vasile Surducan

Routines

  • _ad_init_general - Procedure
  • _adc_init_1_vref - Procedure
  • _adc_init_2_vref - Procedure
  • _adc_init_no_vref - Procedure
  • _adc_read_low_res - Procedure
  • adc_init - Procedure
  • adc_on - Procedure
  • adc_read - Function returns word
  • adc_read_bytes - Procedure
  • adc_read_low_res - Function returns byte


adc_init - JALlib Procedures Help

adc_init JALLIB PROCEDURE

Signature

procedure adc_init() is

Description

Initializes the PIC AD-converter,
by calling the correct routine according to the number of external references
Settings are done according to the special ADC constants
Sets all the analog pins to input
Calculates aquisition time and determines if right or
left justification is optimal

Include

To use this procedure, include the library:

include adc_hardware

Parameters

None

Return Value

None

Example

From sample file: 16f88_adc_lowres.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing how to use adc_hardware library
-- Author: Sebastien Lelong, Copyright (c) 2008..2021, all rights reserved.
-- Adapted-by: Rob Jansen
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: this program shows how to use adc_hardware library. It regurlarly performs an
-- Analog-to-Digital Conversion, on channels AN0 to AN6 (see pin diagrams to know which pins are involved),
-- and sends the result through serial.
--
-- Notes: as output, this sample produces characters on a serial link, and uses delay library.
-- First be sure you're able to run serial and delay tests.
--
-- Few words about diagram: this program performs ADC on channels AN0 to AN6, so you can measure
-- any voltage source connected to these channels (no more than 5V please). To test the whole, you can
-- use a voltage divider. For AN0:
--
--     5V
--     |
--     Z
--     Z R1        -----------
--     Z           |
--     |------ ANx-|   PIC
--     Z           |
--     Z R2        |
--     Z
--     |
--    GND
--
-- - R1=1K, R2=1K: you should get ~127 as ADC value
-- - R1=1K, R2=2.2K: you should get ~175 as ADC value
--
-- Actual output with the above given resistor values (10% tolerance on resistors)
-- and only AN0 and AN1 connected to the resistors, the other inputs floating:
-- Channel 0:123
-- Channel 1:174
-- Channel 2:78
-- Channel 3:43
-- Channel 4:12
-- Channel 5:0
-- Channel 6:0
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- -----------------------------------------------------------------------------
--

include 16f88
-- set all IO as digital, will turn ADC on later (by adc lib)
enable_digital_io()

-- We'll use internal oscillator. It work @ 8MHz
pragma target CLOCK 8_000_000
pragma target OSC INTOSC_NOCLKOUT
-- Specify no postscaler, ie. really runs @8MHz
OSCCON_IRCF = 0b_111
-- no watchdog, please
pragma target WDT		disabled

include print
include delay
const usart_hw_serial = true	-- true = RS232, false = SPI
const serial_hw_baudrate = 19_200
include serial_hardware
serial_hw_init()
-- inform user PIC is ready !
serial_hw_write("!")

-- Step 1: ADC input pin setup we wil use channel 0 to 6 (7 channels)
ANSEL_ANS0 = TRUE
pin_AN0_direction = input
ANSEL_ANS1 = TRUE
pin_AN1_direction = input
ANSEL_ANS2 = TRUE
pin_AN2_direction = input
ANSEL_ANS3 = TRUE
pin_AN3_direction = input
ANSEL_ANS4 = TRUE
pin_AN4_direction = input
ANSEL_ANS5 = TRUE
pin_AN5_direction = input
ANSEL_ANS6 = TRUE
pin_AN6_direction = input
-- Step 2: Set VDD and VSS as Vref
ADCON1_VCFG = 0b00
-- Step 3: Use Frc as ADC clock
ADCON0_ADCS = 0b11
-- The maximum resistance while measuring ADC is... (unit: ohms)
-- Being accurate helps speeding up ADC acquisition
const word ADC_RSOURCE = 2_000
-- Now we can include the library
include adc
-- And initialize the whole with our parameters
adc_init()

-- will periodically send those chars
var byte measure, channel
const byte prefix[] = "Channel "

forever loop

   -- loop over all channels and read
   for 7 using channel loop
      -- get ADC result
      measure = adc_read_low_res(channel)
      -- send it back through serial
      print_string(serial_hw_data,prefix)
      print_byte_dec(serial_hw_data,channel)
      serial_hw_write(":")
      print_byte_dec(serial_hw_data,measure)
      print_crlf(serial_hw_data)
      -- and sleep a little...
      delay_1ms(200)
   end loop

end loop

Generated by JALlib CHM Help System | Source: adc_hardware.jal


adc_off - JAL Language Syntax Reference

adc_off SYNTAX

Description:
-- Device include file for pic18f96j65, containing: -- - Declaration of ports and pins of the chip. -- - Procedures to force the use of the LATx register -- for output when PORTx or pin_xy is addressed. -- - Symbolic definitions for configuration bits (fuses) -- - Some device dependent procedures for common -- operations, like: -- . enable_digital_io() -- -- Sources: -- - {Microchip\MPLABX V6.25 \packs\Microchip}/.../...//PIC18F96J65.PIC --

Notes

-- - This file is generated by script version 2.2 -- - File creation date/time: Sat Mar 22 19:15:24 2025 -- -- ------------------------------------------------ -- const word DEVICE_ID = 0x1F80 -- ID for PIC programmer const word CHIP_ID = 0xD665 -- ID in chipdef_jallib const byte PICTYPE[] = "18F96J65" -- include chipdef_jallib -- common constants -- pragma target cpu PIC_16 -- (banks=16) pragma target chip 18F96J65 pragma target bank 0x0100 pragma stack 31 pragma code 98296 pragma data 0x0-0xE7F,0xF00-0xF5F pragma shared 0x0-0x5F,0xF60-0xFFF -- var volatile byte _pic_accum at 0x0 -- (compiler) -- const word _FUSES_CT = 6 const byte*3 _FUSE_BASE[_FUSES_CT] = { 0x17FF8, 0x17FF9, 0x17FFA, 0x17FFB, 0x17FFC, 0x17FFD } const byte _FUSES[_FUSES_CT] = { 0xE1, -- CONFIG1L 0xF4, -- CONFIG1H 0xC7, -- CONFIG2L 0xFF, -- CONFIG2H 0xF8, -- CONFIG3L 0xF7 -- CONFIG3H } -- -- ------------------------------------------------ var volatile byte MAADR5 at { 0xE80 } -- ------------------------------------------------ var volatile byte MAADR6 at { 0xE81 } -- ------------------------------------------------ var volatile byte MAADR3 at { 0xE82 } -- ------------------------------------------------ var volatile byte MAADR4 at { 0xE83 } -- ------------------------------------------------ var volatile byte MAADR1 at { 0xE84 } -- ------------------------------------------------ var volatile byte MAADR2 at { 0xE85 } -- ------------------------------------------------ var volatile byte MISTAT at { 0xE8A } var volatile bit MISTAT_BUSY at MISTAT : 0 var volatile bit MISTAT_SCAN at MISTAT : 1 var volatile bit MISTAT_NVALID at MISTAT : 2 var volatile bit MISTAT_LINKFL at MISTAT : 3 -- ------------------------------------------------ var volatile byte EFLOCON at { 0xE97 } var volatile bit EFLOCON_FCEN0 at EFLOCON : 0 var volatile bit EFLOCON_FCEN1 at EFLOCON : 1 var volatile bit EFLOCON_FULDPXS at EFLOCON : 2 -- ------------------------------------------------ var volatile word EPAUS at { 0xE98 } -- ------------------------------------------------ var volatile byte EPAUSL at { 0xE98 } -- ------------------------------------------------ var volatile byte EPAUSH at { 0xE99 } -- ------------------------------------------------ var volatile byte MACON1 at { 0xEA0 } var volatile bit MACON1_MARXEN at MACON1 : 0 var volatile bit MACON1_PASSALL at MACON1 : 1 var volatile bit MACON1_RXPAUS at MACON1 : 2 var volatile bit MACON1_TXPAUS at MACON1 : 3 -- ------------------------------------------------ var volatile byte MACON3 at { 0xEA2 } var volatile bit MACON3_FULDPX at MACON3 : 0 var volatile bit MACON3_FRMLNEN at MACON3 : 1 var volatile bit MACON3_HFRMEN at MACON3 : 2 var volatile bit MACON3_PHDREN at MACON3 : 3 var volatile bit MACON3_TXCRCEN at MACON3 : 4 var volatile bit MACON3_PADCFG0 at MACON3 : 5 var volatile bit MACON3_PADCFG1 at MACON3 : 6 var volatile bit MACON3_PADCFG2 at MACON3 : 7 var volatile bit*3 MACON3_PADCFG at MACON3 : 5 -- ------------------------------------------------ var volatile byte MACON4 at { 0xEA3 } var volatile bit MACON4_NOBKOFF at MACON4 : 4 var volatile bit MACON4_BPEN at MACON4 : 5 var volatile bit MACON4_DEFER at MACON4 : 6 -- ------------------------------------------------ var volatile byte MABBIPG at { 0xEA4 } var volatile bit MABBIPG_BBIPG0 at MABBIPG : 0 var volatile bit MABBIPG_BBIPG1 at MABBIPG : 1 var volatile bit MABBIPG_BBIPG2 at MABBIPG : 2 var volatile bit MABBIPG_BBIPG3 at MABBIPG : 3 var volatile bit MABBIPG_BBIPG4 at MABBIPG : 4 var volatile bit MABBIPG_BBIPG5 at MABBIPG : 5 var volatile bit MABBIPG_BBIPG6 at MABBIPG : 6 -- ------------------------------------------------ var volatile word MAIPG at { 0xEA6 } -- ------------------------------------------------ var volatile byte MAIPGL at { 0xEA6 } var volatile bit*7 MAIPGL_MAIPGL at MAIPGL : 0 -- ------------------------------------------------ var volatile byte MAIPGH at { 0xEA7 } var volatile bit*7 MAIPGH_MAIPGH at MAIPGH : 0 -- ------------------------------------------------ var volatile word MAMXFL at { 0xEAA } -- ------------------------------------------------ var volatile byte MAMXFLL at { 0xEAA } -- ------------------------------------------------ var volatile byte MAMXFLH at { 0xEAB } -- ------------------------------------------------ var volatile byte MICMD at { 0xEB2 } var volatile bit MICMD_MIIRD at MICMD : 0 var volatile bit MICMD_MIISCAN at MICMD : 1 -- ------------------------------------------------ var volatile byte MIREGADR at { 0xEB4 } var volatile bit*5 MIREGADR_MIREGADR at MIREGADR : 0 -- ------------------------------------------------ var volatile word MIWR at { 0xEB6 } -- ------------------------------------------------ var volatile byte MIWRL at { 0xEB6 } -- ------------------------------------------------ var volatile byte MIWRH at { 0xEB7 } -- ------------------------------------------------ var volatile word MIRD at { 0xEB8 } -- ------------------------------------------------ var volatile byte MIRDL at { 0xEB8 } -- ------------------------------------------------ var volatile byte MIRDH at { 0xEB9 } -- ------------------------------------------------ var volatile byte EHT0 at { 0xEC0 } -- ------------------------------------------------ var volatile byte EHT1 at { 0xEC1 } -- ------------------------------------------------ var volatile byte EHT2 at { 0xEC2 } -- ------------------------------------------------ var volatile byte EHT3 at { 0xEC3 } -- ------------------------------------------------ var volatile byte EHT4 at { 0xEC4 } -- ------------------------------------------------ var volatile byte EHT5 at { 0xEC5 } -- ------------------------------------------------ var volatile byte EHT6 at { 0xEC6 } -- ------------------------------------------------ var volatile byte EHT7 at { 0xEC7 } -- ------------------------------------------------ var volatile byte EPMM0 at { 0xEC8 } -- ------------------------------------------------ var volatile byte EPMM1 at { 0xEC9 } -- ------------------------------------------------ var volatile byte EPMM2 at { 0xECA } -- ------------------------------------------------ var volatile byte EPMM3 at { 0xECB } -- ------------------------------------------------ var volatile byte EPMM4 at { 0xECC } -- ------------------------------------------------ var volatile byte EPMM5 at { 0xECD } -- ------------------------------------------------ var volatile byte EPMM6 at { 0xECE } -- ------------------------------------------------ var volatile byte EPMM7 at { 0xECF } -- ------------------------------------------------ var volatile word EPMCS at { 0xED0 } -- ------------------------------------------------ var volatile byte EPMCSL at { 0xED0 } -- ------------------------------------------------ var volatile byte EPMCSH at { 0xED1 } -- ------------------------------------------------ var volatile word EPMO at { 0xED4 } -- ------------------------------------------------ var volatile byte EPMOL at { 0xED4 } -- ------------------------------------------------ var volatile byte EPMOH at { 0xED5 } var volatile bit*5 EPMOH_EPMOH at EPMOH : 0 -- ------------------------------------------------ var volatile byte ERXFCON at { 0xED8 } var volatile bit ERXFCON_BCEN at ERXFCON : 0 var volatile bit ERXFCON_MCEN at ERXFCON : 1 var volatile bit ERXFCON_HTEN at ERXFCON : 2 var volatile bit ERXFCON_MPEN at ERXFCON : 3 var volatile bit ERXFCON_PMEN at ERXFCON : 4 var volatile bit ERXFCON_CRCEN at ERXFCON : 5 var volatile bit ERXFCON_ANDOR at ERXFCON : 6 var volatile bit ERXFCON_UCEN at ERXFCON : 7 -- ------------------------------------------------ var volatile byte EPKTCNT at { 0xED9 } -- ------------------------------------------------ var volatile word EWRPT at { 0xEE2 } -- ------------------------------------------------ var volatile byte EWRPTL at { 0xEE2 } -- ------------------------------------------------ var volatile byte EWRPTH at { 0xEE3 } var volatile bit*5 EWRPTH_EWRPTH at EWRPTH : 0 -- ------------------------------------------------ var volatile word ETXST at { 0xEE4 } -- ------------------------------------------------ var volatile byte ETXSTL at { 0xEE4 } -- ------------------------------------------------ var volatile byte ETXSTH at { 0xEE5 } var volatile bit*5 ETXSTH_ETXSTH at ETXSTH : 0 -- ------------------------------------------------ var volatile word ETXND at { 0xEE6 } -- ------------------------------------------------ var volatile byte ETXNDL at { 0xEE6 } -- ------------------------------------------------ var volatile byte ETXNDH at { 0xEE7 } var volatile bit*5 ETXNDH_ETXNDH at ETXNDH : 0 -- ------------------------------------------------ var volatile word ERXST at { 0xEE8 } -- ------------------------------------------------ var volatile byte ERXSTL at { 0xEE8 } -- ------------------------------------------------ var volatile byte ERXSTH at { 0xEE9 } var volatile bit*5 ERXSTH_ERXSTH at ERXSTH : 0 -- ------------------------------------------------ var volatile word ERXND at { 0xEEA } -- ------------------------------------------------ var volatile byte ERXNDL at { 0xEEA } -- ------------------------------------------------ var volatile byte ERXNDH at { 0xEEB } var volatile bit*5 ERXNDH_ERXNDH at ERXNDH : 0 -- ------------------------------------------------ var volatile word ERXRDPT at { 0xEEC } -- ------------------------------------------------ var volatile byte ERXRDPTL at { 0xEEC } -- ------------------------------------------------ var volatile byte ERXRDPTH at { 0xEED } var volatile bit*5 ERXRDPTH_ERXRDPTH at ERXRDPTH : 0 -- ------------------------------------------------ var volatile word ERXWRPT at { 0xEEE } -- ------------------------------------------------ var volatile byte ERXWRPTL at { 0xEEE } -- ------------------------------------------------ var volatile byte ERXWRPTH at { 0xEEF } var volatile bit*5 ERXWRPTH_ERXWRPTH at ERXWRPTH : 0 -- ------------------------------------------------ var volatile word EDMAST at { 0xEF0 } -- ------------------------------------------------ var volatile byte EDMASTL at { 0xEF0 } -- ------------------------------------------------ var volatile byte EDMASTH at { 0xEF1 } var volatile bit*5 EDMASTH_EDMASTH at EDMASTH : 0 -- ------------------------------------------------ var volatile word EDMAND at { 0xEF2 } -- ------------------------------------------------ var volatile byte EDMANDL at { 0xEF2 } -- ------------------------------------------------ var volatile byte EDMANDH at { 0xEF3 } var volatile bit*5 EDMANDH_EDMANDH at EDMANDH : 0 -- ------------------------------------------------ var volatile word EDMADST at { 0xEF4 } -- ------------------------------------------------ var volatile byte EDMADSTL at { 0xEF4 } -- ------------------------------------------------ var volatile byte EDMADSTH at { 0xEF5 } var volatile bit*5 EDMADSTH_EDMADSTH at EDMADSTH : 0 -- ------------------------------------------------ var volatile word EDMACS at { 0xEF6 } -- ------------------------------------------------ var volatile byte EDMACSL at { 0xEF6 } -- ------------------------------------------------ var volatile byte EDMACSH at { 0xEF7 } -- ------------------------------------------------ var volatile byte EIE at { 0xEFB } var volatile bit EIE_RXERIE at EIE : 0 var volatile bit EIE_TXERIE at EIE : 1 var volatile bit EIE_TXIE at EIE : 3 var volatile bit EIE_LINKIE at EIE : 4 var volatile bit EIE_DMAIE at EIE : 5 var volatile bit EIE_PKTIE at EIE : 6 var volatile bit EIE_ETXIE at EIE : 3 -- ------------------------------------------------ var volatile byte ESTAT at { 0xEFD } var volatile bit ESTAT_PHYRDY at ESTAT : 0 var volatile bit ESTAT_TXABRT at ESTAT : 1 var volatile bit ESTAT_RXBUSY at ESTAT : 2 var volatile bit ESTAT_LATECOL at ESTAT : 4 var volatile bit ESTAT_BUFER at ESTAT : 6 -- ------------------------------------------------ var volatile byte ECON2 at { 0xEFE } var volatile bit ECON2_ETHEN at ECON2 : 5 var volatile bit ECON2_PKTDEC at ECON2 : 6 var volatile bit ECON2_AUTOINC at ECON2 : 7 -- ------------------------------------------------ var volatile byte EIR at { 0xF60 } var volatile bit EIR_RXERIF at EIR : 0 var volatile bit EIR_TXERIF at EIR : 1 var volatile bit EIR_TXIF at EIR : 3 var volatile bit EIR_LINKIF at EIR : 4 var volatile bit EIR_DMAIF at EIR : 5 var volatile bit EIR_PKTIF at EIR : 6 var volatile bit EIR_ETXIF at EIR : 3 -- ------------------------------------------------ var volatile byte EDATA at { 0xF61 } var volatile bit EDATA_EDATA0 at EDATA : 0 var volatile bit EDATA_EDATA1 at EDATA : 1 var volatile bit EDATA_EDATA2 at EDATA : 2 var volatile bit EDATA_EDATA3 at EDATA : 3 var volatile bit EDATA_EDATA4 at EDATA : 4 var volatile bit EDATA_EDATA5 at EDATA : 5 var volatile bit EDATA_EDATA6 at EDATA : 6 var volatile bit EDATA_EDATA7 at EDATA : 7 -- ------------------------------------------------ var volatile byte SSP2CON2 at { 0xF62 } var volatile bit SSP2CON2_SEN at SSP2CON2 : 0 var volatile bit SSP2CON2_RSEN at SSP2CON2 : 1 var volatile bit SSP2CON2_PEN at SSP2CON2 : 2 var volatile bit SSP2CON2_RCEN at SSP2CON2 : 3 var volatile bit SSP2CON2_ACKEN at SSP2CON2 : 4 var volatile bit SSP2CON2_ACKDT at SSP2CON2 : 5 var volatile bit SSP2CON2_ACKSTAT at SSP2CON2 : 6 var volatile bit SSP2CON2_GCEN at SSP2CON2 : 7 var volatile bit SSP2CON2_ADMSK1 at SSP2CON2 : 1 var volatile bit SSP2CON2_ADMSK2 at SSP2CON2 : 2 var volatile bit SSP2CON2_ADMSK3 at SSP2CON2 : 3 var volatile bit SSP2CON2_ADMSK4 at SSP2CON2 : 4 var volatile bit SSP2CON2_ADMSK5 at SSP2CON2 : 5 var volatile bit*5 SSP2CON2_ADMSK at SSP2CON2 : 1 var volatile bit SSP2CON2_SEN2 at SSP2CON2 : 0 var volatile bit SSP2CON2_RSEN2 at SSP2CON2 : 1 var volatile bit SSP2CON2_PEN2 at SSP2CON2 : 2 var volatile bit SSP2CON2_RCEN2 at SSP2CON2 : 3 var volatile bit SSP2CON2_ACKEN2 at SSP2CON2 : 4 var volatile bit SSP2CON2_ACKDT2 at SSP2CON2 : 5 var volatile bit SSP2CON2_ACKSTAT2 at SSP2CON2 : 6 var volatile bit SSP2CON2_GCEN2 at SSP2CON2 : 7 var volatile bit SSP2CON2_ADMSK12 at SSP2CON2 : 1 var volatile bit SSP2CON2_ADMSK22 at SSP2CON2 : 2 var volatile bit SSP2CON2_ADMSK32 at SSP2CON2 : 3 var volatile bit SSP2CON2_ADMSK42 at SSP2CON2 : 4 var volatile bit SSP2CON2_ADMSK52 at SSP2CON2 : 5 -- ------------------------------------------------ var volatile byte SSP2CON1 at { 0xF63 } var volatile bit*4 SSP2CON1_SSPM at SSP2CON1 : 0 var volatile bit SSP2CON1_CKP at SSP2CON1 : 4 var volatile bit SSP2CON1_SSPEN at SSP2CON1 : 5 var volatile bit SSP2CON1_SSPOV at SSP2CON1 : 6 var volatile bit SSP2CON1_WCOL at SSP2CON1 : 7 var volatile bit SSP2CON1_SSPM0 at SSP2CON1 : 0 var volatile bit SSP2CON1_SSPM1 at SSP2CON1 : 1 var volatile bit SSP2CON1_SSPM2 at SSP2CON1 : 2 var volatile bit SSP2CON1_SSPM3 at SSP2CON1 : 3 var volatile bit SSP2CON1_SSPM02 at SSP2CON1 : 0 var volatile bit SSP2CON1_SSPM12 at SSP2CON1 : 1 var volatile bit SSP2CON1_SSPM22 at SSP2CON1 : 2 var volatile bit SSP2CON1_SSPM32 at SSP2CON1 : 3 var volatile bit SSP2CON1_CKP2 at SSP2CON1 : 4 var volatile bit SSP2CON1_SSPEN2 at SSP2CON1 : 5 var volatile bit SSP2CON1_SSPOV2 at SSP2CON1 : 6 var volatile bit SSP2CON1_WCOL2 at SSP2CON1 : 7 -- ------------------------------------------------ var volatile byte SSP2STAT at { 0xF64 } var volatile bit SSP2STAT_BF at SSP2STAT : 0 var volatile bit SSP2STAT_UA at SSP2STAT : 1 var volatile bit SSP2STAT_R_NW at SSP2STAT : 2 var volatile bit SSP2STAT_S at SSP2STAT : 3 var volatile bit SSP2STAT_P at SSP2STAT : 4 var volatile bit SSP2STAT_D_NA at SSP2STAT : 5 var volatile bit SSP2STAT_CKE at SSP2STAT : 6 var volatile bit SSP2STAT_SMP at SSP2STAT : 7 var volatile bit SSP2STAT_R_W at SSP2STAT : 2 var volatile bit SSP2STAT_D_A at SSP2STAT : 5 var volatile bit SSP2STAT_I2C_READ at SSP2STAT : 2 var volatile bit SSP2STAT_I2C_START at SSP2STAT : 3 var volatile bit SSP2STAT_I2C_STOP at SSP2STAT : 4 var volatile bit SSP2STAT_I2C_DAT at SSP2STAT : 5 var volatile bit SSP2STAT_NW at SSP2STAT : 2 var volatile bit SSP2STAT_NA at SSP2STAT : 5 var volatile bit SSP2STAT_NWRITE at SSP2STAT : 2 var volatile bit SSP2STAT_NADDRESS at SSP2STAT : 5 var volatile bit SSP2STAT_READ_WRITE at SSP2STAT : 2 var volatile bit SSP2STAT_DATA_ADDRESS at SSP2STAT : 5 var volatile bit SSP2STAT_R at SSP2STAT : 2 var volatile bit SSP2STAT_D at SSP2STAT : 5 var volatile bit SSP2STAT_BF2 at SSP2STAT : 0 var volatile bit SSP2STAT_UA2 at SSP2STAT : 1 var volatile bit SSP2STAT_RW2 at SSP2STAT : 2 var volatile bit SSP2STAT_START2 at SSP2STAT : 3 var volatile bit SSP2STAT_STOP2 at SSP2STAT : 4 var volatile bit SSP2STAT_DA2 at SSP2STAT : 5 var volatile bit SSP2STAT_CKE2 at SSP2STAT : 6 var volatile bit SSP2STAT_SMP2 at SSP2STAT : 7 var volatile bit SSP2STAT_I2C_READ2 at SSP2STAT : 2 var volatile bit SSP2STAT_I2C_START2 at SSP2STAT : 3 var volatile bit SSP2STAT_I2C_STOP2 at SSP2STAT : 4 var volatile bit SSP2STAT_DATA_ADDRESS2 at SSP2STAT : 5 var volatile bit SSP2STAT_READ_WRITE2 at SSP2STAT : 2 var volatile bit SSP2STAT_S2 at SSP2STAT : 3 var volatile bit SSP2STAT_P2 at SSP2STAT : 4 var volatile bit SSP2STAT_D_A2 at SSP2STAT : 5 var volatile bit SSP2STAT_R_W2 at SSP2STAT : 2 var volatile bit SSP2STAT_D_NA2 at SSP2STAT : 5 var volatile bit SSP2STAT_R_NW2 at SSP2STAT : 2 var volatile bit SSP2STAT_I2C_DAT2 at SSP2STAT : 5 var volatile bit SSP2STAT_NW2 at SSP2STAT : 2 var volatile bit SSP2STAT_NA2 at SSP2STAT : 5 var volatile bit SSP2STAT_NWRITE2 at SSP2STAT : 2 var volatile bit SSP2STAT_NADDRESS2 at SSP2STAT : 5 -- ------------------------------------------------ var volatile byte SSP2ADD at { 0xF65 } -- ------------------------------------------------ var volatile byte SSP2BUF at { 0xF66 } -- ------------------------------------------------ var volatile byte ECCP2DEL at { 0xF67 } var volatile bit*7 ECCP2DEL_PDC at ECCP2DEL : 0 var volatile bit ECCP2DEL_PRSEN at ECCP2DEL : 7 var volatile bit ECCP2DEL_PDC0 at ECCP2DEL : 0 var volatile bit ECCP2DEL_PDC1 at ECCP2DEL : 1 var volatile bit ECCP2DEL_PDC2 at ECCP2DEL : 2 var volatile bit ECCP2DEL_PDC3 at ECCP2DEL : 3 var volatile bit ECCP2DEL_PDC4 at ECCP2DEL : 4 var volatile bit ECCP2DEL_PDC5 at ECCP2DEL : 5 var volatile bit ECCP2DEL_PDC6 at ECCP2DEL : 6 var volatile bit ECCP2DEL_P2DC0 at ECCP2DEL : 0 var volatile bit ECCP2DEL_P2DC1 at ECCP2DEL : 1 var volatile bit ECCP2DEL_P2DC2 at ECCP2DEL : 2 var volatile bit ECCP2DEL_P2DC3 at ECCP2DEL : 3 var volatile bit ECCP2DEL_P2DC4 at ECCP2DEL : 4 var volatile bit ECCP2DEL_P2DC5 at ECCP2DEL : 5 var volatile bit ECCP2DEL_P2DC6 at ECCP2DEL : 6 var volatile bit ECCP2DEL_P2RSEN at ECCP2DEL : 7 -- ------------------------------------------------ var volatile byte ECCP2AS at { 0xF68 } var volatile bit*2 ECCP2AS_PSSBD at ECCP2AS : 0 var volatile bit*2 ECCP2AS_PSSAC at ECCP2AS : 2 var volatile bit*3 ECCP2AS_ECCPAS at ECCP2AS : 4 var volatile bit ECCP2AS_ECCPASE at ECCP2AS : 7 var volatile bit ECCP2AS_PSSBD0 at ECCP2AS : 0 var volatile bit ECCP2AS_PSSBD1 at ECCP2AS : 1 var volatile bit ECCP2AS_PSSAC0 at ECCP2AS : 2 var volatile bit ECCP2AS_PSSAC1 at ECCP2AS : 3 var volatile bit ECCP2AS_ECCPAS0 at ECCP2AS : 4 var volatile bit ECCP2AS_ECCPAS1 at ECCP2AS : 5 var volatile bit ECCP2AS_ECCPAS2 at ECCP2AS : 6 var volatile bit ECCP2AS_PSS2BD0 at ECCP2AS : 0 var volatile bit ECCP2AS_PSS2BD1 at ECCP2AS : 1 var volatile bit ECCP2AS_PSS2AC0 at ECCP2AS : 2 var volatile bit ECCP2AS_PSS2AC1 at ECCP2AS : 3 var volatile bit ECCP2AS_ECCP2AS0 at ECCP2AS : 4 var volatile bit ECCP2AS_ECCP2AS1 at ECCP2AS : 5 var volatile bit ECCP2AS_ECCP2AS2 at ECCP2AS : 6 var volatile bit ECCP2AS_ECCP2ASE at ECCP2AS : 7 -- ------------------------------------------------ var volatile byte ECCP3DEL at { 0xF69 } var volatile bit*7 ECCP3DEL_PDC at ECCP3DEL : 0 var volatile bit ECCP3DEL_PRSEN at ECCP3DEL : 7 var volatile bit ECCP3DEL_PDC0 at ECCP3DEL : 0 var volatile bit ECCP3DEL_PDC1 at ECCP3DEL : 1 var volatile bit ECCP3DEL_PDC2 at ECCP3DEL : 2 var volatile bit ECCP3DEL_PDC3 at ECCP3DEL : 3 var volatile bit ECCP3DEL_PDC4 at ECCP3DEL : 4 var volatile bit ECCP3DEL_PDC5 at ECCP3DEL : 5 var volatile bit ECCP3DEL_PDC6 at ECCP3DEL : 6 var volatile bit ECCP3DEL_P3DC0 at ECCP3DEL : 0 var volatile bit ECCP3DEL_P3DC1 at ECCP3DEL : 1 var volatile bit ECCP3DEL_P3DC2 at ECCP3DEL : 2 var volatile bit ECCP3DEL_P3DC3 at ECCP3DEL : 3 var volatile bit ECCP3DEL_P3DC4 at ECCP3DEL : 4 var volatile bit ECCP3DEL_P3DC5 at ECCP3DEL : 5 var volatile bit ECCP3DEL_P3DC6 at ECCP3DEL : 6 var volatile bit ECCP3DEL_P3RSEN at ECCP3DEL : 7 -- ------------------------------------------------ var volatile byte ECCP3AS at { 0xF6A } var volatile bit*2 ECCP3AS_PSSBD at ECCP3AS : 0 var volatile bit*2 ECCP3AS_PSSAC at ECCP3AS : 2 var volatile bit*3 ECCP3AS_ECCPAS at ECCP3AS : 4 var volatile bit ECCP3AS_ECCPASE at ECCP3AS : 7 var volatile bit ECCP3AS_PSSBD0 at ECCP3AS : 0 var volatile bit ECCP3AS_PSSBD1 at ECCP3AS : 1 var volatile bit ECCP3AS_PSSAC0 at ECCP3AS : 2 var volatile bit ECCP3AS_PSSAC1 at ECCP3AS : 3 var volatile bit ECCP3AS_ECCPAS0 at ECCP3AS : 4 var volatile bit ECCP3AS_ECCPAS1 at ECCP3AS : 5 var volatile bit ECCP3AS_ECCPAS2 at ECCP3AS : 6 var volatile bit ECCP3AS_PSS3BD0 at ECCP3AS : 0 var volatile bit ECCP3AS_PSS3BD1 at ECCP3AS : 1 var volatile bit ECCP3AS_PSS3AC0 at ECCP3AS : 2 var volatile bit ECCP3AS_PSS3AC1 at ECCP3AS : 3 var volatile bit ECCP3AS_ECCP3AS0 at ECCP3AS : 4 var volatile bit ECCP3AS_ECCP3AS1 at ECCP3AS : 5 var volatile bit ECCP3AS_ECCP3AS2 at ECCP3AS : 6 var volatile bit ECCP3AS_ECCP3ASE at ECCP3AS : 7 -- ------------------------------------------------ var volatile byte RCSTA2 at { 0xF6B } var volatile bit RCSTA2_RX9D at RCSTA2 : 0 var volatile bit RCSTA2_OERR at RCSTA2 : 1 var volatile bit RCSTA2_FERR at RCSTA2 : 2 var volatile bit RCSTA2_ADDEN at RCSTA2 : 3 var volatile bit RCSTA2_CREN at RCSTA2 : 4 var volatile bit RCSTA2_SREN at RCSTA2 : 5 var volatile bit RCSTA2_RX9 at RCSTA2 : 6 var volatile bit RCSTA2_SPEN at RCSTA2 : 7 var volatile bit RCSTA2_RCD8 at RCSTA2 : 0 var volatile bit RCSTA2_RC9 at RCSTA2 : 6 var volatile bit RCSTA2_NRC8 at RCSTA2 : 6 var volatile bit RCSTA2_RC8_9 at RCSTA2 : 6 var volatile bit RCSTA2_RX9D2 at RCSTA2 : 0 var volatile bit RCSTA2_OERR2 at RCSTA2 : 1 var volatile bit RCSTA2_FERR2 at RCSTA2 : 2 var volatile bit RCSTA2_ADDEN2 at RCSTA2 : 3 var volatile bit RCSTA2_CREN2 at RCSTA2 : 4 var volatile bit RCSTA2_SREN2 at RCSTA2 : 5 var volatile bit RCSTA2_RX92 at RCSTA2 : 6 var volatile bit RCSTA2_SPEN2 at RCSTA2 : 7 var volatile bit RCSTA2_RCD82 at RCSTA2 : 0 var volatile bit RCSTA2_RC8_92 at RCSTA2 : 6 var volatile bit RCSTA2_RC92 at RCSTA2 : 6 -- ------------------------------------------------ var volatile byte TXSTA2 at { 0xF6C } var volatile bit TXSTA2_TX9D at TXSTA2 : 0 var volatile bit TXSTA2_TRMT at TXSTA2 : 1 var volatile bit TXSTA2_BRGH at TXSTA2 : 2 var volatile bit TXSTA2_SENDB at TXSTA2 : 3 var volatile bit TXSTA2_SYNC at TXSTA2 : 4 var volatile bit TXSTA2_TXEN at TXSTA2 : 5 var volatile bit TXSTA2_TX9 at TXSTA2 : 6 var volatile bit TXSTA2_CSRC at TXSTA2 : 7 var volatile bit TXSTA2_TXD8 at TXSTA2 : 0 var volatile bit TXSTA2_TX8_9 at TXSTA2 : 6 var volatile bit TXSTA2_NTX8 at TXSTA2 : 6 var volatile bit TXSTA2_TX9D2 at TXSTA2 : 0 var volatile bit TXSTA2_TRMT2 at TXSTA2 : 1 var volatile bit TXSTA2_BRGH2 at TXSTA2 : 2 var volatile bit TXSTA2_SENDB2 at TXSTA2 : 3 var volatile bit TXSTA2_SYNC2 at TXSTA2 : 4 var volatile bit TXSTA2_TXEN2 at TXSTA2 : 5 var volatile bit TXSTA2_TX92 at TXSTA2 : 6 var volatile bit TXSTA2_CSRC2 at TXSTA2 : 7 var volatile bit TXSTA2_TXD82 at TXSTA2 : 0 var volatile bit TXSTA2_TX8_92 at TXSTA2 : 6 -- ------------------------------------------------ var volatile byte TXREG2 at { 0xF6D } -- ------------------------------------------------ var volatile byte RCREG2 at { 0xF6E } -- ------------------------------------------------ var volatile byte SPBRG2 at { 0xF6F } alias SPBRGL2 is SPBRG2 -- ------------------------------------------------ var volatile byte CCP5CON at { 0xF70 } var volatile bit*4 CCP5CON_CCP5M at CCP5CON : 0 alias CCP5CON_MODE is CCP5CON_CCP5M var volatile bit*2 CCP5CON_DC5B at CCP5CON : 4 var volatile bit CCP5CON_CCP5M0 at CCP5CON : 0 var volatile bit CCP5CON_CCP5M1 at CCP5CON : 1 var volatile bit CCP5CON_CCP5M2 at CCP5CON : 2 var volatile bit CCP5CON_CCP5M3 at CCP5CON : 3 var volatile bit CCP5CON_CCP5Y at CCP5CON : 4 var volatile bit CCP5CON_CCP5X at CCP5CON : 5 var volatile bit CCP5CON_DC5B0 at CCP5CON : 4 var volatile bit CCP5CON_DC5B1 at CCP5CON : 5 -- ------------------------------------------------ var volatile word CCPR5 at { 0xF71 } -- ------------------------------------------------ var volatile byte CCPR5L at { 0xF71 } -- ------------------------------------------------ var volatile byte CCPR5H at { 0xF72 } -- ------------------------------------------------ var volatile byte CCP4CON at { 0xF73 } var volatile bit*4 CCP4CON_CCP4M at CCP4CON : 0 alias CCP4CON_MODE is CCP4CON_CCP4M var volatile bit*2 CCP4CON_DC4B at CCP4CON : 4 var volatile bit CCP4CON_CCP4M0 at CCP4CON : 0 var volatile bit CCP4CON_CCP4M1 at CCP4CON : 1 var volatile bit CCP4CON_CCP4M2 at CCP4CON : 2 var volatile bit CCP4CON_CCP4M3 at CCP4CON : 3 var volatile bit CCP4CON_DC4B0 at CCP4CON : 4 var volatile bit CCP4CON_DC4B1 at CCP4CON : 5 var volatile bit CCP4CON_CCP4Y at CCP4CON : 4 var volatile bit CCP4CON_CCP4X at CCP4CON : 5 -- ------------------------------------------------ var volatile word CCPR4 at { 0xF74 } -- ------------------------------------------------ var volatile byte CCPR4L at { 0xF74 } -- ------------------------------------------------ var volatile byte CCPR4H at { 0xF75 } -- ------------------------------------------------ var volatile byte T4CON at { 0xF76 } var volatile bit*2 T4CON_T4CKPS at T4CON : 0 var volatile bit T4CON_TMR4ON at T4CON : 2 var volatile bit*4 T4CON_T4OUTPS at T4CON : 3 var volatile bit T4CON_T4CKPS0 at T4CON : 0 var volatile bit T4CON_T4CKPS1 at T4CON : 1 var volatile bit T4CON_T4OUTPS0 at T4CON : 3 var volatile bit T4CON_T4OUTPS1 at T4CON : 4 var volatile bit T4CON_T4OUTPS2 at T4CON : 5 var volatile bit T4CON_T4OUTPS3 at T4CON : 6 -- ------------------------------------------------ var volatile byte PR4 at { 0xF77 } -- ------------------------------------------------ var volatile byte TMR4 at { 0xF78 } -- ------------------------------------------------ var volatile byte ECCP1DEL at { 0xF79 } var volatile bit*7 ECCP1DEL_PDC at ECCP1DEL : 0 var volatile bit ECCP1DEL_PRSEN at ECCP1DEL : 7 var volatile bit ECCP1DEL_PDC0 at ECCP1DEL : 0 var volatile bit ECCP1DEL_PDC1 at ECCP1DEL : 1 var volatile bit ECCP1DEL_PDC2 at ECCP1DEL : 2 var volatile bit ECCP1DEL_PDC3 at ECCP1DEL : 3 var volatile bit ECCP1DEL_PDC4 at ECCP1DEL : 4 var volatile bit ECCP1DEL_PDC5 at ECCP1DEL : 5 var volatile bit ECCP1DEL_PDC6 at ECCP1DEL : 6 var volatile bit ECCP1DEL_P1DC0 at ECCP1DEL : 0 var volatile bit ECCP1DEL_P1DC1 at ECCP1DEL : 1 var volatile bit ECCP1DEL_P1DC2 at ECCP1DEL : 2 var volatile bit ECCP1DEL_P1DC3 at ECCP1DEL : 3 var volatile bit ECCP1DEL_P1DC4 at ECCP1DEL : 4 var volatile bit ECCP1DEL_P1DC5 at ECCP1DEL : 5 var volatile bit ECCP1DEL_P1DC6 at ECCP1DEL : 6 var volatile bit ECCP1DEL_P1RSEN at ECCP1DEL : 7 -- ------------------------------------------------ var volatile word ERDPT at { 0xF7A } -- ------------------------------------------------ var volatile byte ERDPTL at { 0xF7A } -- ------------------------------------------------ var volatile byte ERDPTH at { 0xF7B } var volatile bit*5 ERDPTH_ERDPTH at ERDPTH : 0 -- ------------------------------------------------ var volatile byte BAUDCON2 at { 0xF7C } var volatile bit BAUDCON2_ABDEN at BAUDCON2 : 0 var volatile bit BAUDCON2_WUE at BAUDCON2 : 1 var volatile bit BAUDCON2_BRG16 at BAUDCON2 : 3 var volatile bit BAUDCON2_TXCKP at BAUDCON2 : 4 var volatile bit BAUDCON2_RXDTP at BAUDCON2 : 5 var volatile bit BAUDCON2_RCIDL at BAUDCON2 : 6 var volatile bit BAUDCON2_ABDOVF at BAUDCON2 : 7 var volatile bit BAUDCON2_SCKP at BAUDCON2 : 4 var volatile bit BAUDCON2_RCMT at BAUDCON2 : 6 var volatile bit BAUDCON2_ABDEN2 at BAUDCON2 : 0 var volatile bit BAUDCON2_WUE2 at BAUDCON2 : 1 var volatile bit BAUDCON2_BRG162 at BAUDCON2 : 3 var volatile bit BAUDCON2_TXCKP2 at BAUDCON2 : 4 var volatile bit BAUDCON2_RXDTP2 at BAUDCON2 : 5 var volatile bit BAUDCON2_RCIDL2 at BAUDCON2 : 6 var volatile bit BAUDCON2_ABDOVF2 at BAUDCON2 : 7 var volatile bit BAUDCON2_SCKP2 at BAUDCON2 : 4 var volatile bit BAUDCON2_DTRXP2 at BAUDCON2 : 5 var volatile bit BAUDCON2_RCMT2 at BAUDCON2 : 6 -- ------------------------------------------------ var volatile byte SPBRGH2 at { 0xF7D } -- ------------------------------------------------ var volatile byte BAUDCON1 at { 0xF7E } var volatile bit BAUDCON1_ABDEN at BAUDCON1 : 0 var volatile bit BAUDCON1_WUE at BAUDCON1 : 1 var volatile bit BAUDCON1_BRG16 at BAUDCON1 : 3 var volatile bit BAUDCON1_TXCKP at BAUDCON1 : 4 var volatile bit BAUDCON1_RXDTP at BAUDCON1 : 5 var volatile bit BAUDCON1_RCIDL at BAUDCON1 : 6 var volatile bit BAUDCON1_ABDOVF at BAUDCON1 : 7 var volatile bit BAUDCON1_SCKP at BAUDCON1 : 4 var volatile bit BAUDCON1_RCMT at BAUDCON1 : 6 var volatile bit BAUDCON1_ABDEN1 at BAUDCON1 : 0 var volatile bit BAUDCON1_WUE1 at BAUDCON1 : 1 var volatile bit BAUDCON1_BRG161 at BAUDCON1 : 3 var volatile bit BAUDCON1_CKTXP at BAUDCON1 : 4 var volatile bit BAUDCON1_DTRXP at BAUDCON1 : 5 var volatile bit BAUDCON1_RCIDL1 at BAUDCON1 : 6 var volatile bit BAUDCON1_ABDOVF1 at BAUDCON1 : 7 var volatile bit BAUDCON1_SCKP1 at BAUDCON1 : 4 var volatile bit BAUDCON1_DTRXP1 at BAUDCON1 : 5 var volatile bit BAUDCON1_RCMT1 at BAUDCON1 : 6 var volatile bit BAUDCON1_TXCKP1 at BAUDCON1 : 4 var volatile bit BAUDCON1_RXDTP1 at BAUDCON1 : 5 -- alias BAUDCON is BAUDCON1 alias BAUDCON_ABDEN is BAUDCON1_ABDEN alias BAUDCON_WUE is BAUDCON1_WUE alias BAUDCON_BRG16 is BAUDCON1_BRG16 alias BAUDCON_TXCKP is BAUDCON1_TXCKP alias BAUDCON_RXDTP is BAUDCON1_RXDTP alias BAUDCON_RCIDL is BAUDCON1_RCIDL alias BAUDCON_ABDOVF is BAUDCON1_ABDOVF alias BAUDCON_SCKP is BAUDCON1_SCKP alias BAUDCON_RCMT is BAUDCON1_RCMT alias BAUDCON_ABDEN1 is BAUDCON1_ABDEN1 alias BAUDCON_WUE1 is BAUDCON1_WUE1 alias BAUDCON_BRG161 is BAUDCON1_BRG161 alias BAUDCON_CKTXP is BAUDCON1_CKTXP alias BAUDCON_DTRXP is BAUDCON1_DTRXP alias BAUDCON_RCIDL1 is BAUDCON1_RCIDL1 alias BAUDCON_ABDOVF1 is BAUDCON1_ABDOVF1 alias BAUDCON_SCKP1 is BAUDCON1_SCKP1 alias BAUDCON_DTRXP1 is BAUDCON1_DTRXP1 alias BAUDCON_RCMT1 is BAUDCON1_RCMT1 alias BAUDCON_TXCKP1 is BAUDCON1_TXCKP1 alias BAUDCON_RXDTP1 is BAUDCON1_RXDTP1 -- ------------------------------------------------ var volatile byte SPBRGH1 at { 0xF7F } -- alias SPBRGH is SPBRGH1 -- ------------------------------------------------ var volatile byte PORTA at { 0xF80 } var volatile bit PORTA_RA0 at PORTA : 0 var volatile bit PORTA_RA1 at PORTA : 1 var volatile bit PORTA_RA2 at PORTA : 2 var volatile bit PORTA_RA3 at PORTA : 3 var volatile bit PORTA_RA4 at PORTA : 4 var volatile bit PORTA_RA5 at PORTA : 5 var volatile bit PORTA_RJPU at PORTA : 7 var volatile bit PORTA_AN0 at PORTA : 0 var volatile bit PORTA_AN1 at PORTA : 1 var volatile bit PORTA_AN2 at PORTA : 2 var volatile bit PORTA_AN3 at PORTA : 3 var volatile bit PORTA_T0CKI at PORTA : 4 var volatile bit PORTA_AN4 at PORTA : 5 var volatile bit PORTA_LEDA at PORTA : 0 var volatile bit PORTA_LEDB at PORTA : 1 var volatile bit PORTA_VREFM at PORTA : 2 var volatile bit PORTA_VREFP at PORTA : 3 var volatile bit PORTA_ULPWUIN at PORTA : 0 var volatile bit PORTA_LVDIN at PORTA : 5 var volatile bit PORTA_RA7 at PORTA : 7 -- ------------------------------------------------ var volatile byte PORTB at { 0xF81 } var volatile bit PORTB_RB0 at PORTB : 0 var volatile bit PORTB_RB1 at PORTB : 1 var volatile bit PORTB_RB2 at PORTB : 2 var volatile bit PORTB_RB3 at PORTB : 3 var volatile bit PORTB_RB4 at PORTB : 4 var volatile bit PORTB_RB5 at PORTB : 5 var volatile bit PORTB_RB6 at PORTB : 6 var volatile bit PORTB_RB7 at PORTB : 7 var volatile bit PORTB_INT0 at PORTB : 0 var volatile bit PORTB_INT1 at PORTB : 1 var volatile bit PORTB_INT2 at PORTB : 2 var volatile bit PORTB_INT3 at PORTB : 3 var volatile bit PORTB_KBI0 at PORTB : 4 var volatile bit PORTB_KBI1 at PORTB : 5 var volatile bit PORTB_KBI2 at PORTB : 6 var volatile bit PORTB_KBI3 at PORTB : 7 var volatile bit PORTB_FLT0 at PORTB : 0 var volatile bit PORTB_CCP2 at PORTB : 3 var volatile bit PORTB_PGC at PORTB : 6 var volatile bit PORTB_PGD at PORTB : 7 var volatile bit PORTB_ECCP2 at PORTB : 3 var volatile bit PORTB_CCP2_PA2 at PORTB : 3 -- ------------------------------------------------ var volatile byte PORTC at { 0xF82 } var volatile bit PORTC_RC0 at PORTC : 0 var volatile bit PORTC_RC1 at PORTC : 1 var volatile bit PORTC_RC2 at PORTC : 2 var volatile bit PORTC_RC3 at PORTC : 3 var volatile bit PORTC_RC4 at PORTC : 4 var volatile bit PORTC_RC5 at PORTC : 5 var volatile bit PORTC_RC6 at PORTC : 6 var volatile bit PORTC_RC7 at PORTC : 7 var volatile bit PORTC_T1OSO at PORTC : 0 var volatile bit PORTC_T1OSI at PORTC : 1 var volatile bit PORTC_CCP1 at PORTC : 2 var volatile bit PORTC_SCK at PORTC : 3 var volatile bit PORTC_SDI at PORTC : 4 var volatile bit PORTC_SDO at PORTC : 5 var volatile bit PORTC_TX at PORTC : 6 var volatile bit PORTC_RX at PORTC : 7 var volatile bit PORTC_T13CKI at PORTC : 0 var volatile bit PORTC_CCP2 at PORTC : 1 var volatile bit PORTC_SCL at PORTC : 3 var volatile bit PORTC_SDA at PORTC : 4 var volatile bit PORTC_CK at PORTC : 6 var volatile bit PORTC_DT at PORTC : 7 var volatile bit PORTC_ECCP2 at PORTC : 1 var volatile bit PORTC_ECCP1 at PORTC : 2 var volatile bit PORTC_SCK1 at PORTC : 3 var volatile bit PORTC_SDI1 at PORTC : 4 var volatile bit PORTC_SDO1 at PORTC : 5 var volatile bit PORTC_TX1 at PORTC : 6 var volatile bit PORTC_RX1 at PORTC : 7 var volatile bit PORTC_SCL1 at PORTC : 3 var volatile bit PORTC_SDA1 at PORTC : 4 var volatile bit PORTC_CK1 at PORTC : 6 var volatile bit PORTC_DT1 at PORTC : 7 var volatile bit PORTC_PA2 at PORTC : 1 var volatile bit PORTC_PA1 at PORTC : 2 -- ------------------------------------------------ var volatile byte PORTD at { 0xF83 } var volatile bit PORTD_RD0 at PORTD : 0 var volatile bit PORTD_RD1 at PORTD : 1 var volatile bit PORTD_RD2 at PORTD : 2 var volatile bit PORTD_RD3 at PORTD : 3 var volatile bit PORTD_RD4 at PORTD : 4 var volatile bit PORTD_RD5 at PORTD : 5 var volatile bit PORTD_RD6 at PORTD : 6 var volatile bit PORTD_RD7 at PORTD : 7 var volatile bit PORTD_PSP0 at PORTD : 0 var volatile bit PORTD_PSP1 at PORTD : 1 var volatile bit PORTD_PSP2 at PORTD : 2 var volatile bit PORTD_PSP3 at PORTD : 3 var volatile bit PORTD_PSP4 at PORTD : 4 var volatile bit PORTD_PSP5 at PORTD : 5 var volatile bit PORTD_PSP6 at PORTD : 6 var volatile bit PORTD_PSP7 at PORTD : 7 var volatile bit PORTD_AD0 at PORTD : 0 var volatile bit PORTD_AD1 at PORTD : 1 var volatile bit PORTD_AD2 at PORTD : 2 var volatile bit PORTD_AD3 at PORTD : 3 var volatile bit PORTD_AD4 at PORTD : 4 var volatile bit PORTD_AD5 at PORTD : 5 var volatile bit PORTD_AD6 at PORTD : 6 var volatile bit PORTD_AD7 at PORTD : 7 var volatile bit PORTD_SDA2 at PORTD : 5 var volatile bit PORTD_SCL2 at PORTD : 6 var volatile bit PORTD_SS2 at PORTD : 7 var volatile bit PORTD_SDO2 at PORTD : 4 var volatile bit PORTD_SDI2 at PORTD : 5 var volatile bit PORTD_SCK2 at PORTD : 6 var volatile bit PORTD_NSS2 at PORTD : 7 -- ------------------------------------------------ var volatile byte PORTE at { 0xF84 } var volatile bit PORTE_RE0 at PORTE : 0 var volatile bit PORTE_RE1 at PORTE : 1 var volatile bit PORTE_RE2 at PORTE : 2 var volatile bit PORTE_RE3 at PORTE : 3 var volatile bit PORTE_RE4 at PORTE : 4 var volatile bit PORTE_RE5 at PORTE : 5 var volatile bit PORTE_RE6 at PORTE : 6 var volatile bit PORTE_RE7 at PORTE : 7 var volatile bit PORTE_RD at PORTE : 0 var volatile bit PORTE_WR at PORTE : 1 var volatile bit PORTE_CS at PORTE : 2 var volatile bit PORTE_CCP2 at PORTE : 7 var volatile bit PORTE_AD8 at PORTE : 0 var volatile bit PORTE_AD9 at PORTE : 1 var volatile bit PORTE_AD10 at PORTE : 2 var volatile bit PORTE_AD11 at PORTE : 3 var volatile bit PORTE_AD12 at PORTE : 4 var volatile bit PORTE_AD13 at PORTE : 5 var volatile bit PORTE_AD14 at PORTE : 6 var volatile bit PORTE_AD15 at PORTE : 7 var volatile bit PORTE_NRD at PORTE : 0 var volatile bit PORTE_NWR at PORTE : 1 var volatile bit PORTE_NCS at PORTE : 2 var volatile bit PORTE_ECCP2 at PORTE : 7 var volatile bit PORTE_PD2 at PORTE : 0 var volatile bit PORTE_PC2 at PORTE : 1 var volatile bit PORTE_CCP10 at PORTE : 2 var volatile bit PORTE_CCP9E at PORTE : 3 var volatile bit PORTE_CCP8E at PORTE : 4 var volatile bit PORTE_CCP7E at PORTE : 5 var volatile bit PORTE_CCP6E at PORTE : 6 var volatile bit PORTE_CCP2E at PORTE : 7 var volatile bit PORTE_RDE at PORTE : 0 var volatile bit PORTE_WRE at PORTE : 1 var volatile bit PORTE_PB2 at PORTE : 2 var volatile bit PORTE_PC3E at PORTE : 3 var volatile bit PORTE_PB3E at PORTE : 4 var volatile bit PORTE_PC1E at PORTE : 5 var volatile bit PORTE_PB1E at PORTE : 6 var volatile bit PORTE_PA2E at PORTE : 7 -- ------------------------------------------------ var volatile byte PORTF at { 0xF85 } var volatile bit PORTF_RF0 at PORTF : 0 var volatile bit PORTF_RF1 at PORTF : 1 var volatile bit PORTF_RF2 at PORTF : 2 var volatile bit PORTF_RF3 at PORTF : 3 var volatile bit PORTF_RF4 at PORTF : 4 var volatile bit PORTF_RF5 at PORTF : 5 var volatile bit PORTF_RF6 at PORTF : 6 var volatile bit PORTF_RF7 at PORTF : 7 var volatile bit PORTF_AN5 at PORTF : 0 var volatile bit PORTF_AN6 at PORTF : 1 var volatile bit PORTF_AN7 at PORTF : 2 var volatile bit PORTF_AN8 at PORTF : 3 var volatile bit PORTF_AN9 at PORTF : 4 var volatile bit PORTF_AN10 at PORTF : 5 var volatile bit PORTF_AN11 at PORTF : 6 var volatile bit PORTF_SS at PORTF : 7 var volatile bit PORTF_CVREF at PORTF : 5 var volatile bit PORTF_NSS at PORTF : 7 var volatile bit PORTF_SS1 at PORTF : 7 var volatile bit PORTF_NSS1 at PORTF : 7 var volatile bit PORTF_C2OUTF at PORTF : 1 var volatile bit PORTF_C1OUTF at PORTF : 2 -- ------------------------------------------------ var volatile byte PORTG at { 0xF86 } var volatile bit PORTG_RG0 at PORTG : 0 var volatile bit PORTG_RG1 at PORTG : 1 var volatile bit PORTG_RG2 at PORTG : 2 var volatile bit PORTG_RG3 at PORTG : 3 var volatile bit PORTG_RG4 at PORTG : 4 var volatile bit PORTG_RG5 at PORTG : 5 var volatile bit PORTG_RG6 at PORTG : 6 var volatile bit PORTG_RG7 at PORTG : 7 var volatile bit PORTG_CCP3 at PORTG : 0 var volatile bit PORTG_TX2 at PORTG : 1 var volatile bit PORTG_RX2 at PORTG : 2 var volatile bit PORTG_CCP4 at PORTG : 3 var volatile bit PORTG_CCP5 at PORTG : 4 var volatile bit PORTG_ECCP3 at PORTG : 0 var volatile bit PORTG_CK2 at PORTG : 1 var volatile bit PORTG_DT2 at PORTG : 2 var volatile bit PORTG_C3OUTG at PORTG : 1 var volatile bit PORTG_RJPU at PORTG : 5 -- ------------------------------------------------ var volatile byte PORTH at { 0xF87 } var volatile bit PORTH_RH0 at PORTH : 0 var volatile bit PORTH_RH1 at PORTH : 1 var volatile bit PORTH_RH2 at PORTH : 2 var volatile bit PORTH_RH3 at PORTH : 3 var volatile bit PORTH_RH4 at PORTH : 4 var volatile bit PORTH_RH5 at PORTH : 5 var volatile bit PORTH_RH6 at PORTH : 6 var volatile bit PORTH_RH7 at PORTH : 7 var volatile bit PORTH_AD16 at PORTH : 0 var volatile bit PORTH_AD17 at PORTH : 1 var volatile bit PORTH_AD18 at PORTH : 2 var volatile bit PORTH_AD19 at PORTH : 3 var volatile bit PORTH_AN12 at PORTH : 4 var volatile bit PORTH_AN13 at PORTH : 5 var volatile bit PORTH_AN14 at PORTH : 6 var volatile bit PORTH_AN15 at PORTH : 7 var volatile bit PORTH_CCP9 at PORTH : 4 var volatile bit PORTH_CCP8 at PORTH : 5 var volatile bit PORTH_CCP7 at PORTH : 6 var volatile bit PORTH_CCP6 at PORTH : 7 var volatile bit PORTH_PC3 at PORTH : 4 var volatile bit PORTH_PB3 at PORTH : 5 var volatile bit PORTH_PC1 at PORTH : 6 var volatile bit PORTH_PB1 at PORTH : 7 -- ------------------------------------------------ var volatile byte PORTJ at { 0xF88 } var volatile bit PORTJ_RJ0 at PORTJ : 0 var volatile bit PORTJ_RJ1 at PORTJ : 1 var volatile bit PORTJ_RJ2 at PORTJ : 2 var volatile bit PORTJ_RJ3 at PORTJ : 3 var volatile bit PORTJ_RJ4 at PORTJ : 4 var volatile bit PORTJ_RJ5 at PORTJ : 5 var volatile bit PORTJ_RJ6 at PORTJ : 6 var volatile bit PORTJ_RJ7 at PORTJ : 7 var volatile bit PORTJ_ALE at PORTJ : 0 var volatile bit PORTJ_OE at PORTJ : 1 var volatile bit PORTJ_WRL at PORTJ : 2 var volatile bit PORTJ_WRH at PORTJ : 3 var volatile bit PORTJ_BA0 at PORTJ : 4 var volatile bit PORTJ_CE at PORTJ : 5 var volatile bit PORTJ_LB at PORTJ : 6 var volatile bit PORTJ_UB at PORTJ : 7 var volatile bit PORTJ_NOE at PORTJ : 1 var volatile bit PORTJ_NWRL at PORTJ : 2 var volatile bit PORTJ_NWRH at PORTJ : 3 var volatile bit PORTJ_NCE at PORTJ : 5 var volatile bit PORTJ_NLB at PORTJ : 6 var volatile bit PORTJ_NUB at PORTJ : 7 -- ------------------------------------------------ var volatile byte LATA at { 0xF89 } --

Generated by JAL Syntax Documentation System | Source: DITA


adc_on - JALlib Procedures Help

adc_on JALLIB PROCEDURE

Signature

procedure adc_on() is

Description

Turns all ADC channels back on

Include

To use this procedure, include the library:

include adc_hardware

Parameters

None

Return Value

None

Example

From sample file: 18f4550_usb_hid_generic.jal

-- Title: USB HID generic device demo
-- Author: Albert Faber, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample implements a generic HID device. The advantage of a generic
-- HID device is that it can use the HID driver on the HOST operation system.
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: compiled with following flags
-- -loader18 -no-fuse -no-variable-reuse
-- -no-variable-reuse must be used
--  due to a compiler issue
--
-- ------------------------------------------------------
-- ------------------------------------------------------
--
-- compiled with following flags: -loader18 -no-fuse -no-variable-reuse
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_usb_hid_generic.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

include delay

;@jallib section serial

-- whether or not using the serial port
const HAS_SERIAL_DEBUG_PORT = 1

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure
end if

const bit USB_DEBUG = false
const bit USB_DEBUG_HIGH = false

const bit USB_HID_DEBUG = false
const bit USB_HID_DEBUG_HIGH = false
const byte USB_HID_ENDPOINT = 0x01

include usb_defs

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 8
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = 8
const word USB_EP1_IN_ADDR  = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )

var volatile byte  usb_ep1in_buf[ 8 ] at USB_EP1_IN_ADDR

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte HID_OUT_REPORT_SIZE = 8

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    0x08,		-- max packet size for end point 0
    0x25,
    0x09,		-- Vendor ID
    0x01,
    0x70,		-- Product ID
    0x01,
    0x00, 	    -- version 0.1 of the product
    0x01,		-- string 1 for manufacturer
    0x02,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const byte USB_HID_REPORT1[]=
{

    0x06, 0xA0, 0xFF,			-- Usage page (vendor defined)
    0x09, 0x01,					-- Usage ID (vendor defined)
    0xA1, 0x01,					-- Collection (application)

    -- The Input report
    0x09, 0x03,     			-- Usage ID - vendor defined
    0x15, 0x00,     			-- Logical Minimum (0)
    0x26, 0xFF, 0x00,   		-- Logical Maximum (255)
    0x75, 0x08,     			-- Report Size (8 bits)
    0x95, HID_OUT_REPORT_SIZE, 	-- Report Count	(8 fields)
    0x81, 0x02,     			-- Input (Data, Variable, Absolute)

    -- The Output report
    0x09, 0x04,     			-- Usage ID - vendor defined
    0x15, 0x00,     			-- Logical Minimum (0)
    0x26, 0xFF, 0x00,   		-- Logical Maximum (255)
    0x75, 0x08,     			-- Report Size (8 bits)
    0x95, HID_OUT_REPORT_SIZE,  -- Report Count (8 fields)
    0x91, 0x02,      			-- Output (Data, Variable, Absolute)

    -- The Feature report
    0x09, 0x05,     			-- Usage ID - vendor defined
    0x15, 0x00,     			-- Logical Minimum (0)
    0x26, 0xFF, 0x00,   		-- Logical Maximum (255)
    0x75, 0x08,					-- Report Size (8 bits)
    0x95, HID_OUT_REPORT_SIZE, 	-- Report Count	(8 fields)
    0xB1, 0x02,     			-- Feature (Data, Variable, Absolute)

    0xC0						-- end collection
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,	-- length,
    USB_DT_INTERFACE,	-- descriptor_type,
    0x00,	-- interface_number, (starts at zero)
    0x00,	-- alternate_setting, (no alternatives)
    0x02,	-- num_endpoints,
    USB_HID_INTF,	-- interface_class, (HID)
    0x00,	-- interface_subclass
    0x00,	-- interface_protocol
    0x00,	-- interface_string_id;

    -- hid descriptor - - - - - - - - - - - - - - -
    0x09,				-- length,
    USB_DT_HID,			-- descriptor_type;
    0x11,
    0x01,				-- hid_spec in BCD (1.11)
    0x00,				-- country_code, (0=not country specific)
    0x01,				-- num_class_descriptors, (1)
    USB_DT_HID_REPORT,	-- class_descriptor_type; (0x22 = report)
    (count( USB_HID_REPORT1 ) & 0xFF ),
    (count( USB_HID_REPORT1 ) >> 8 ),

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_INT,			-- attributes; (Interrupt)
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x01,				-- interval (1ms)

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_INT,		-- attributes; (Interrupt)
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x01				-- interval (1ms)
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

const byte USB_STRING1[18] =
{
    18,				-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    " ", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    ".", 0x00
}

const byte USB_STRING2[48] =
{
    48,				-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    " ", 0x00,
    "G", 0x00,
    "e", 0x00,
    "n", 0x00,
    "e", 0x00,
    "r", 0x00,
    "i", 0x00,
    "c", 0x00,
    " ", 0x00,
    "H", 0x00,
    "I", 0x00,
    "D", 0x00,
    " ", 0x00,
    "D", 0x00,
    "e", 0x00,
    "m", 0x00,
    "o", 0x00
}

include usb_drv_core

-- adc lib is horribly broken, it won't work K50 series, so disable for the time being
if ( 	(target_chip == PIC_18F14K50 ) |
        (target_chip == PIC_18F13K50 ) |
        (target_chip == PIC_18LF14K50 ) |
        (target_chip == PIC_18LF13K50 ) )then
    const bit no_analog = true
else
    const bit no_analog = true
end if

if !no_analog	then
    -------------------------------- ADC STUFF -------------------------------------
    const no_adc = 0x06
    const ADC_HARDWARE_NCHAN     = 1
    const ADC_HARDWARE_NVREF     = 0         ;number of external references
    const ADC_HARDWARE_RSOURCE   = 10_000    ;maximum source resistance
    const ADC_HARDWARE_HIGH_RESOLUTION = true ;true = high resolution = 10 bits

    -- get the library, after defining the constants
    include adc_hardware

    -- initialize the AD converter according to the above parameters
    -- LEFT JUSTIFIED, 16 TAD, FOSC / 64
    ADCON2 = 0b_10_000_110
    adc_init()
    adc_on()
end if

-- -----------------------------------------------------------------------------

-- timer 0 offset value
const byte TMR0_OFFSET = 106

------------------------------------------------------------
-- TIMER 0 configuration
------------------------------------------------------------
-- Objection is to get a 0.1 millisecond delay
-- fclk = 48 Mhz => timer clk = fclk / 4 = 12 Mhz
-- required clock rate: 0.1 ms => 1 Khz
-- timer 0 should divide by => 12 Mhz / 1 KHz = 12000
-- set pre-scaler to 1:8 and count to 150
--
-- TMR0_OFFSET = ( 256 - 150 ) = 106
-- TMR0_delay=(256-TMR0_OFFSET)*4*prescaler/Fosc
-- TMR0_delay=(256-6)*4*4/20_000_000= 0.1 msec.
--
-- Init TMR0, free run mode,
------------------------------------------------------------

-- set timer 0, 8 bit mode, timer enabled
T0CON = 0b_11000_010

var word num_timer_ints = 0

var volatile bit usb_hid_can_tx = true

const byte USB_HID_REQ_HID 			= 0x21
const byte USB_HID_REQ_REPORT 		= 0x22
const byte USB_HID_REQ_PHYSDISCR	= 0x23

const byte USB_HCR_GET_REPORT		= 0x01
const byte USB_HCR_GET_IDLE			= 0x02
const byte USB_HCR_GET_PROTOCOL		= 0x03
const byte USB_HCR_SET_REPORT		= 0x09
const byte USB_HCR_SET_IDLE			= 0x0A
const byte USB_HCR_SET_PROTOCOL		= 0x0B

var byte hid_tx_buffer[ HID_OUT_REPORT_SIZE ]
var bit send_tx = false

var bit adc_enabled = false

-- TMR0 interrupt service routine
procedure timer_0_isr() is
    pragma interrupt

    if ( INTCON_TMR0IF )  then
        num_timer_ints = num_timer_ints + 1

        if ( num_timer_ints == 100 ) then
            -- send portA event
            hid_tx_buffer[ 0 ] = 0x10
            hid_tx_buffer[ 1 ] = PORTA

            send_tx = true
        end if

        if ( num_timer_ints == 200 ) then
            -- send portB event
            hid_tx_buffer[ 0 ] = 0x11
            hid_tx_buffer[ 1 ] = PORTB

            send_tx = true
        end if

        if ( num_timer_ints == 300 ) then
            -- send portC event
            hid_tx_buffer[ 0 ] = 0x12
            hid_tx_buffer[ 1 ] = PORTC

            send_tx = true
        end if

        if ( num_timer_ints == 400 ) then
            -- send ADC event
            hid_tx_buffer[ 0 ] = 0x13

            send_tx = true
        end if

        -- only send value every 100 ms second
        if ( num_timer_ints == 1000 ) then

            num_timer_ints = 0

            if adc_enabled then
                var byte adc_hbyte = 0x80
                var byte adc_lbyte = 0x00

if !no_analog then
                adc_read_bytes( 0 , adc_hbyte, adc_lbyte)
end if
                -- send ADC event
                hid_tx_buffer[ 0 ] = 0x02
                hid_tx_buffer[ 1 ] = adc_hbyte
                hid_tx_buffer[ 2 ] = adc_lbyte

                send_tx = true

            end if
        end if
        -- Do timer offset TMR0_OFFSET
        TMR0 = TMR0 + TMR0_OFFSET

        -- Clear timer 0 interrupt flag
        INTCON_TMR0IF = low
    end if

end procedure

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    if USB_HID_DEBUG_HIGH then
        const byte str[] = " EP data in: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_byte_hex(serial_hw_data,byte_count & 0xFF)
        print_string(serial_hw_data,str1)
    end if

    -- data has been sent, so do we need to send more?
    if (end_point == USB_HID_ENDPOINT) then
        -- it's the data end point
        usb_hid_can_tx = true

    end if
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline

    var byte cdc_rx_next

    if USB_HID_DEBUG then
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_byte_hex(serial_hw_data,byte_count)
        serial_hw_write( " " )
        print_byte_hex(serial_hw_data, end_point )
        print_string(serial_hw_data,str1)
    end if

    -- We have some data!
    if (end_point == USB_HID_ENDPOINT) then
        var byte src_ptr[2] AT buffer_addr

        FSR1L = src_ptr[0]
        FSR1H = src_ptr[1]

        if USB_HID_DEBUG then
            serial_newline()
        end if

        var byte index
        var byte cmd
        for byte_count using index loop
            var byte value
            value = POSTINC1
            if index  == 0 then
                cmd = value
                hid_tx_buffer[ 0 ] = value
            end if
            if index  == 1 then
                hid_tx_buffer[ 1 ] = value
            end if

            if USB_HID_DEBUG then
                print_byte_hex(serial_hw_data,value)
                serial_hw_write( " " )
            end if
        end loop

        send_tx = true

        case cmd of
            0x01:
            block
                -- enable interrupts (timer 0 )
                INTCON_TMR0IE = high
                INTCON_GIE = high
            end block

            0x02:
            block
                -- enable interrupts (timer 0 )
                INTCON_TMR0IE = low
                INTCON_GIE = low
            end block

            0x03:
            block
                PORTC = hid_tx_buffer[ 1 ]
                if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                end if
            end block

            0x04:
            block
                adc_enabled = true
            end block

            0x05:
            block
                adc_enabled = false
            end block

            otherwise
            block

            end block
        end case
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- set port A and B to inputs
PORTA_direction  = 0b_1111_1111
PORTC_direction  = all_output

-- constants
const  byte str_welcome[] = "JAL USB Generic HID demo version 0.10\nplease wait (takes ~10 seconds) before the device is fully configured"

-- variables
var word i = 0
var bit usb_initialized = false

var byte hid_report_in[8]

var word ticks100us = 0
var bit enable_keyboard = false

procedure usb_tasks() is
    -- Servicing Hardware
    -- use polling method
    usb_handle_isr()
    if ( send_tx ) then
        usb_send_data(USB_HID_ENDPOINT, hid_tx_buffer, count( hid_tx_buffer ), low )
        send_tx = false
    end if

end procedure

procedure usb_hid_tx_report( byte in hid_report_in[], byte in cnt ) is

    while ( usb_hid_can_tx == false ) loop
        usb_tasks()
    end loop
    usb_hid_can_tx = false
    usb_send_data(USB_HID_ENDPOINT, hid_report_in, cnt , low )
end procedure

-- interrupts? No thanks
while INTCON_GIE loop
    INTCON_GIE = false
end loop

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

-- setup the USB device
usb_setup()

-- enable USB device
usb_enable_module()

-- enable digital inputs on port B
-- enable_digital_io()

ADCON1 = 0x0E

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_tasks()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

        -- note user via serial line that USB has been configured
        if usb_initialized == false then
            usb_initialized = true

            if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                const  byte str[] = "USB device has been configured by the HOST!"
                print_string(serial_hw_data, str )
                serial_newline()

                -- now keyboard chars can be send to the host
                enable_keyboard = true
            end if
        end if
    end if

    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

end loop

Generated by JALlib CHM Help System | Source: adc_hardware.jal


adc_read_bytes - JALlib Procedures Help

adc_read_bytes JALLIB PROCEDURE

Signature

procedure adc_read_bytes(byte in adc_chan, byte out adc_hbyte, byte out adc_lbyte) is

Description

Does an AD conversion on the selected channel
returns the 10-bit result as 2 byte parameters
It doesn't matter if ADC is set to low or high resolution

Include

To use this procedure, include the library:

include adc_hardware

Parameters

  • adc_chan - byte in
  • adc_hbyte - byte out
  • adc_lbyte - byte out

Return Value

None

Example

From sample file: 18f4550_usb_hid_generic.jal

-- Title: USB HID generic device demo
-- Author: Albert Faber, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample implements a generic HID device. The advantage of a generic
-- HID device is that it can use the HID driver on the HOST operation system.
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: compiled with following flags
-- -loader18 -no-fuse -no-variable-reuse
-- -no-variable-reuse must be used
--  due to a compiler issue
--
-- ------------------------------------------------------
-- ------------------------------------------------------
--
-- compiled with following flags: -loader18 -no-fuse -no-variable-reuse
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_usb_hid_generic.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

include delay

;@jallib section serial

-- whether or not using the serial port
const HAS_SERIAL_DEBUG_PORT = 1

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure
end if

const bit USB_DEBUG = false
const bit USB_DEBUG_HIGH = false

const bit USB_HID_DEBUG = false
const bit USB_HID_DEBUG_HIGH = false
const byte USB_HID_ENDPOINT = 0x01

include usb_defs

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 8
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = 8
const word USB_EP1_IN_ADDR  = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )

var volatile byte  usb_ep1in_buf[ 8 ] at USB_EP1_IN_ADDR

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte HID_OUT_REPORT_SIZE = 8

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    0x08,		-- max packet size for end point 0
    0x25,
    0x09,		-- Vendor ID
    0x01,
    0x70,		-- Product ID
    0x01,
    0x00, 	    -- version 0.1 of the product
    0x01,		-- string 1 for manufacturer
    0x02,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const byte USB_HID_REPORT1[]=
{

    0x06, 0xA0, 0xFF,			-- Usage page (vendor defined)
    0x09, 0x01,					-- Usage ID (vendor defined)
    0xA1, 0x01,					-- Collection (application)

    -- The Input report
    0x09, 0x03,     			-- Usage ID - vendor defined
    0x15, 0x00,     			-- Logical Minimum (0)
    0x26, 0xFF, 0x00,   		-- Logical Maximum (255)
    0x75, 0x08,     			-- Report Size (8 bits)
    0x95, HID_OUT_REPORT_SIZE, 	-- Report Count	(8 fields)
    0x81, 0x02,     			-- Input (Data, Variable, Absolute)

    -- The Output report
    0x09, 0x04,     			-- Usage ID - vendor defined
    0x15, 0x00,     			-- Logical Minimum (0)
    0x26, 0xFF, 0x00,   		-- Logical Maximum (255)
    0x75, 0x08,     			-- Report Size (8 bits)
    0x95, HID_OUT_REPORT_SIZE,  -- Report Count (8 fields)
    0x91, 0x02,      			-- Output (Data, Variable, Absolute)

    -- The Feature report
    0x09, 0x05,     			-- Usage ID - vendor defined
    0x15, 0x00,     			-- Logical Minimum (0)
    0x26, 0xFF, 0x00,   		-- Logical Maximum (255)
    0x75, 0x08,					-- Report Size (8 bits)
    0x95, HID_OUT_REPORT_SIZE, 	-- Report Count	(8 fields)
    0xB1, 0x02,     			-- Feature (Data, Variable, Absolute)

    0xC0						-- end collection
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,	-- length,
    USB_DT_INTERFACE,	-- descriptor_type,
    0x00,	-- interface_number, (starts at zero)
    0x00,	-- alternate_setting, (no alternatives)
    0x02,	-- num_endpoints,
    USB_HID_INTF,	-- interface_class, (HID)
    0x00,	-- interface_subclass
    0x00,	-- interface_protocol
    0x00,	-- interface_string_id;

    -- hid descriptor - - - - - - - - - - - - - - -
    0x09,				-- length,
    USB_DT_HID,			-- descriptor_type;
    0x11,
    0x01,				-- hid_spec in BCD (1.11)
    0x00,				-- country_code, (0=not country specific)
    0x01,				-- num_class_descriptors, (1)
    USB_DT_HID_REPORT,	-- class_descriptor_type; (0x22 = report)
    (count( USB_HID_REPORT1 ) & 0xFF ),
    (count( USB_HID_REPORT1 ) >> 8 ),

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_INT,			-- attributes; (Interrupt)
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x01,				-- interval (1ms)

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_INT,		-- attributes; (Interrupt)
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x01				-- interval (1ms)
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

const byte USB_STRING1[18] =
{
    18,				-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    " ", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    ".", 0x00
}

const byte USB_STRING2[48] =
{
    48,				-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    " ", 0x00,
    "G", 0x00,
    "e", 0x00,
    "n", 0x00,
    "e", 0x00,
    "r", 0x00,
    "i", 0x00,
    "c", 0x00,
    " ", 0x00,
    "H", 0x00,
    "I", 0x00,
    "D", 0x00,
    " ", 0x00,
    "D", 0x00,
    "e", 0x00,
    "m", 0x00,
    "o", 0x00
}

include usb_drv_core

-- adc lib is horribly broken, it won't work K50 series, so disable for the time being
if ( 	(target_chip == PIC_18F14K50 ) |
        (target_chip == PIC_18F13K50 ) |
        (target_chip == PIC_18LF14K50 ) |
        (target_chip == PIC_18LF13K50 ) )then
    const bit no_analog = true
else
    const bit no_analog = true
end if

if !no_analog	then
    -------------------------------- ADC STUFF -------------------------------------
    const no_adc = 0x06
    const ADC_HARDWARE_NCHAN     = 1
    const ADC_HARDWARE_NVREF     = 0         ;number of external references
    const ADC_HARDWARE_RSOURCE   = 10_000    ;maximum source resistance
    const ADC_HARDWARE_HIGH_RESOLUTION = true ;true = high resolution = 10 bits

    -- get the library, after defining the constants
    include adc_hardware

    -- initialize the AD converter according to the above parameters
    -- LEFT JUSTIFIED, 16 TAD, FOSC / 64
    ADCON2 = 0b_10_000_110
    adc_init()
    adc_on()
end if

-- -----------------------------------------------------------------------------

-- timer 0 offset value
const byte TMR0_OFFSET = 106

------------------------------------------------------------
-- TIMER 0 configuration
------------------------------------------------------------
-- Objection is to get a 0.1 millisecond delay
-- fclk = 48 Mhz => timer clk = fclk / 4 = 12 Mhz
-- required clock rate: 0.1 ms => 1 Khz
-- timer 0 should divide by => 12 Mhz / 1 KHz = 12000
-- set pre-scaler to 1:8 and count to 150
--
-- TMR0_OFFSET = ( 256 - 150 ) = 106
-- TMR0_delay=(256-TMR0_OFFSET)*4*prescaler/Fosc
-- TMR0_delay=(256-6)*4*4/20_000_000= 0.1 msec.
--
-- Init TMR0, free run mode,
------------------------------------------------------------

-- set timer 0, 8 bit mode, timer enabled
T0CON = 0b_11000_010

var word num_timer_ints = 0

var volatile bit usb_hid_can_tx = true

const byte USB_HID_REQ_HID 			= 0x21
const byte USB_HID_REQ_REPORT 		= 0x22
const byte USB_HID_REQ_PHYSDISCR	= 0x23

const byte USB_HCR_GET_REPORT		= 0x01
const byte USB_HCR_GET_IDLE			= 0x02
const byte USB_HCR_GET_PROTOCOL		= 0x03
const byte USB_HCR_SET_REPORT		= 0x09
const byte USB_HCR_SET_IDLE			= 0x0A
const byte USB_HCR_SET_PROTOCOL		= 0x0B

var byte hid_tx_buffer[ HID_OUT_REPORT_SIZE ]
var bit send_tx = false

var bit adc_enabled = false

-- TMR0 interrupt service routine
procedure timer_0_isr() is
    pragma interrupt

    if ( INTCON_TMR0IF )  then
        num_timer_ints = num_timer_ints + 1

        if ( num_timer_ints == 100 ) then
            -- send portA event
            hid_tx_buffer[ 0 ] = 0x10
            hid_tx_buffer[ 1 ] = PORTA

            send_tx = true
        end if

        if ( num_timer_ints == 200 ) then
            -- send portB event
            hid_tx_buffer[ 0 ] = 0x11
            hid_tx_buffer[ 1 ] = PORTB

            send_tx = true
        end if

        if ( num_timer_ints == 300 ) then
            -- send portC event
            hid_tx_buffer[ 0 ] = 0x12
            hid_tx_buffer[ 1 ] = PORTC

            send_tx = true
        end if

        if ( num_timer_ints == 400 ) then
            -- send ADC event
            hid_tx_buffer[ 0 ] = 0x13

            send_tx = true
        end if

        -- only send value every 100 ms second
        if ( num_timer_ints == 1000 ) then

            num_timer_ints = 0

            if adc_enabled then
                var byte adc_hbyte = 0x80
                var byte adc_lbyte = 0x00

if !no_analog then
                adc_read_bytes( 0 , adc_hbyte, adc_lbyte)
end if
                -- send ADC event
                hid_tx_buffer[ 0 ] = 0x02
                hid_tx_buffer[ 1 ] = adc_hbyte
                hid_tx_buffer[ 2 ] = adc_lbyte

                send_tx = true

            end if
        end if
        -- Do timer offset TMR0_OFFSET
        TMR0 = TMR0 + TMR0_OFFSET

        -- Clear timer 0 interrupt flag
        INTCON_TMR0IF = low
    end if

end procedure

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    if USB_HID_DEBUG_HIGH then
        const byte str[] = " EP data in: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_byte_hex(serial_hw_data,byte_count & 0xFF)
        print_string(serial_hw_data,str1)
    end if

    -- data has been sent, so do we need to send more?
    if (end_point == USB_HID_ENDPOINT) then
        -- it's the data end point
        usb_hid_can_tx = true

    end if
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline

    var byte cdc_rx_next

    if USB_HID_DEBUG then
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_byte_hex(serial_hw_data,byte_count)
        serial_hw_write( " " )
        print_byte_hex(serial_hw_data, end_point )
        print_string(serial_hw_data,str1)
    end if

    -- We have some data!
    if (end_point == USB_HID_ENDPOINT) then
        var byte src_ptr[2] AT buffer_addr

        FSR1L = src_ptr[0]
        FSR1H = src_ptr[1]

        if USB_HID_DEBUG then
            serial_newline()
        end if

        var byte index
        var byte cmd
        for byte_count using index loop
            var byte value
            value = POSTINC1
            if index  == 0 then
                cmd = value
                hid_tx_buffer[ 0 ] = value
            end if
            if index  == 1 then
                hid_tx_buffer[ 1 ] = value
            end if

            if USB_HID_DEBUG then
                print_byte_hex(serial_hw_data,value)
                serial_hw_write( " " )
            end if
        end loop

        send_tx = true

        case cmd of
            0x01:
            block
                -- enable interrupts (timer 0 )
                INTCON_TMR0IE = high
                INTCON_GIE = high
            end block

            0x02:
            block
                -- enable interrupts (timer 0 )
                INTCON_TMR0IE = low
                INTCON_GIE = low
            end block

            0x03:
            block
                PORTC = hid_tx_buffer[ 1 ]
                if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                end if
            end block

            0x04:
            block
                adc_enabled = true
            end block

            0x05:
            block
                adc_enabled = false
            end block

            otherwise
            block

            end block
        end case
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- set port A and B to inputs
PORTA_direction  = 0b_1111_1111
PORTC_direction  = all_output

-- constants
const  byte str_welcome[] = "JAL USB Generic HID demo version 0.10\nplease wait (takes ~10 seconds) before the device is fully configured"

-- variables
var word i = 0
var bit usb_initialized = false

var byte hid_report_in[8]

var word ticks100us = 0
var bit enable_keyboard = false

procedure usb_tasks() is
    -- Servicing Hardware
    -- use polling method
    usb_handle_isr()
    if ( send_tx ) then
        usb_send_data(USB_HID_ENDPOINT, hid_tx_buffer, count( hid_tx_buffer ), low )
        send_tx = false
    end if

end procedure

procedure usb_hid_tx_report( byte in hid_report_in[], byte in cnt ) is

    while ( usb_hid_can_tx == false ) loop
        usb_tasks()
    end loop
    usb_hid_can_tx = false
    usb_send_data(USB_HID_ENDPOINT, hid_report_in, cnt , low )
end procedure

-- interrupts? No thanks
while INTCON_GIE loop
    INTCON_GIE = false
end loop

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

-- setup the USB device
usb_setup()

-- enable USB device
usb_enable_module()

-- enable digital inputs on port B
-- enable_digital_io()

ADCON1 = 0x0E

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_tasks()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

        -- note user via serial line that USB has been configured
        if usb_initialized == false then
            usb_initialized = true

            if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                const  byte str[] = "USB device has been configured by the HOST!"
                print_string(serial_hw_data, str )
                serial_newline()

                -- now keyboard chars can be send to the host
                enable_keyboard = true
            end if
        end if
    end if

    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

end loop

Generated by JALlib CHM Help System | Source: adc_hardware.jal


adc_read_high_res - JALlib Procedures Help

adc_read_high_res JALLIB FUNCTION

Signature

function adc_read_high_res(byte in adc_chan) return word is

Description

Title: Analog to digital conversion returning a 16-bits value
Arguments: channel number
Returns: 16-bits ADC value
Notes: - Uses right justification
- Returns a 16-bits value of the result of ADC, of which the
range is dependent of the supported ADC resolution of the PIC
(can be a 8-, 10-, 12-bits value).
- When the PIC supports only 8-bits ADC resolution the
result is the same as of adc_read_low_res().

Include

To use this procedure, include the library:

include adc

Parameters

  • adc_chan - byte in

Return Value

word - 16-bits ADC value

Example

From sample file: 16f18323_adc.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing how to use adc_library for a PIC16F18323
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program shows how to use adc library. It regurlarly performs a
--              high resultion and low resolution Analog-to-Digital Conversion
--              on pin AN4 (ADC channel 4) and sends the result through serial.
--
--  Notes: To test the whole ADC range we use a potentiometer of 10K connected between
--         +5V and Ground. The PIC should also run at +5V in this case.
--
--         +5V
--          |
--          |
--          |           -----------
--         |-|          |
--         | |<---- AN4-|   PIC
--         |-|          |
--          |  10k      |
--          |
--          |
--         ---
--         GND
--
--         The low resolution range should be from 0 to 255.
--         The high resolution range should be from 0 to 1023
--
include 16f18323                                  -- target PIC

-- Use internal oscillator 32 MHz.
pragma target CLOCK     32_000_000
--
pragma target OSC      OFF                       -- internal oscillator
pragma target RSTOSC   HFINT32                   -- select 32 MHz
pragma target CLKOUTEN DISABLED                  -- no clock output
pragma target WDT      DISABLED                  -- watchdog
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
OSCCON1_NDIV = 0b0000                            -- Fosc 32 / 1 = 32 MHz

enable_digital_io()                              -- set all IO as digital

-- Step 1: ADC analog input pin setup
const byte ADC_CHANNEL = 4                       -- Potmeter connected to pin_A4
ANSELA_ANSA4 = TRUE                              -- Channel 4 is analog input
-- Step 2: Set VDD and VSS as Vref
ADCON1_ADPREF = 0b00
ADCON1_ADNREF = FALSE
-- Step 3: Use Frc as ADC clock
ADCON1_ADCS = 0b111
const ADC_RSOURCE = 10_000                       -- Input resistance: 10K potmeter
-- Now we can include the library
include adc
-- And initialize the whole with our parameters
adc_init()

-- Setup the serial hardware. Also maps the TX pin.
-- PPS is needed to set the USART pins correctly.
include pps
pps_control_lock(FALSE)
-- Change following lines to match your pcb layout.
RC4PPS = PPS_TX  -- TX assigned to C4
RXPPS  = PPS_RC3 -- RX assigned to C3
pps_control_lock(TRUE)

-- Serial interface definitions.
const serial_hw_baudrate = 115_200
alias pin_tx_direction is pin_C4_direction
alias pin_rx_direction is pin_C3_direction
include serial_hardware
serial_hw_init()

-- We want to print some strings and values of variables.
include print

-- Used variables
var word measure_highres
var byte measure_lowres

-- Main program
forever loop

   -- Get results in high resolution and print it.
   measure_highres = adc_read_high_res(ADC_CHANNEL)
   print_string(serial_hw_data, "ADC high resolution value is: ")
   print_word_dec(serial_hw_data,measure_highres)
   print_crlf(serial_hw_data)

   -- Get results in low resolution and print it.
   measure_lowres = adc_read_low_res(ADC_CHANNEL)
   print_string(serial_hw_data, "ADC low resolution value is: ")
   print_byte_dec(serial_hw_data, measure_lowres)
   print_crlf(serial_hw_data)

   -- Do not overflow the serial interface.
   _usec_delay(100_000)
   print_crlf(serial_hw_data)

end loop

Generated by JALlib CHM Help System | Source: adc.jal


adc_read_low_res - JALlib Procedures Help

adc_read_low_res JALLIB FUNCTION

Signature

function adc_read_low_res(byte in adc_chan) return byte is

Description

Returns Low Resolution ADC-value as the RESULT
It doesn't matter if ADC is set to low or high resolution

Include

To use this procedure, include the library:

include adc_hardware

Parameters

  • adc_chan - byte in

Return Value

byte - Function return value

Example

From sample file: 16f88_adc_lowres.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing how to use adc_hardware library
-- Author: Sebastien Lelong, Copyright (c) 2008..2021, all rights reserved.
-- Adapted-by: Rob Jansen
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: this program shows how to use adc_hardware library. It regurlarly performs an
-- Analog-to-Digital Conversion, on channels AN0 to AN6 (see pin diagrams to know which pins are involved),
-- and sends the result through serial.
--
-- Notes: as output, this sample produces characters on a serial link, and uses delay library.
-- First be sure you're able to run serial and delay tests.
--
-- Few words about diagram: this program performs ADC on channels AN0 to AN6, so you can measure
-- any voltage source connected to these channels (no more than 5V please). To test the whole, you can
-- use a voltage divider. For AN0:
--
--     5V
--     |
--     Z
--     Z R1        -----------
--     Z           |
--     |------ ANx-|   PIC
--     Z           |
--     Z R2        |
--     Z
--     |
--    GND
--
-- - R1=1K, R2=1K: you should get ~127 as ADC value
-- - R1=1K, R2=2.2K: you should get ~175 as ADC value
--
-- Actual output with the above given resistor values (10% tolerance on resistors)
-- and only AN0 and AN1 connected to the resistors, the other inputs floating:
-- Channel 0:123
-- Channel 1:174
-- Channel 2:78
-- Channel 3:43
-- Channel 4:12
-- Channel 5:0
-- Channel 6:0
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- -----------------------------------------------------------------------------
--

include 16f88
-- set all IO as digital, will turn ADC on later (by adc lib)
enable_digital_io()

-- We'll use internal oscillator. It work @ 8MHz
pragma target CLOCK 8_000_000
pragma target OSC INTOSC_NOCLKOUT
-- Specify no postscaler, ie. really runs @8MHz
OSCCON_IRCF = 0b_111
-- no watchdog, please
pragma target WDT		disabled

include print
include delay
const usart_hw_serial = true	-- true = RS232, false = SPI
const serial_hw_baudrate = 19_200
include serial_hardware
serial_hw_init()
-- inform user PIC is ready !
serial_hw_write("!")

-- Step 1: ADC input pin setup we wil use channel 0 to 6 (7 channels)
ANSEL_ANS0 = TRUE
pin_AN0_direction = input
ANSEL_ANS1 = TRUE
pin_AN1_direction = input
ANSEL_ANS2 = TRUE
pin_AN2_direction = input
ANSEL_ANS3 = TRUE
pin_AN3_direction = input
ANSEL_ANS4 = TRUE
pin_AN4_direction = input
ANSEL_ANS5 = TRUE
pin_AN5_direction = input
ANSEL_ANS6 = TRUE
pin_AN6_direction = input
-- Step 2: Set VDD and VSS as Vref
ADCON1_VCFG = 0b00
-- Step 3: Use Frc as ADC clock
ADCON0_ADCS = 0b11
-- The maximum resistance while measuring ADC is... (unit: ohms)
-- Being accurate helps speeding up ADC acquisition
const word ADC_RSOURCE = 2_000
-- Now we can include the library
include adc
-- And initialize the whole with our parameters
adc_init()

-- will periodically send those chars
var byte measure, channel
const byte prefix[] = "Channel "

forever loop

   -- loop over all channels and read
   for 7 using channel loop
      -- get ADC result
      measure = adc_read_low_res(channel)
      -- send it back through serial
      print_string(serial_hw_data,prefix)
      print_byte_dec(serial_hw_data,channel)
      serial_hw_write(":")
      print_byte_dec(serial_hw_data,measure)
      print_crlf(serial_hw_data)
      -- and sleep a little...
      delay_1ms(200)
   end loop

end loop

Generated by JALlib CHM Help System | Source: adc_hardware.jal


ads7843_get_touch_coordinate - JALlib Procedures Help

ads7843_get_touch_coordinate JALLIB FUNCTION

Signature

function ads7843_get_touch_coordinate(word out touch_x, word out touch_y) return bit is

Description

Get the x and y coordinate where the screen was touched and returns TRUE
when the screen was touched. X and y are returned in touch screen values.

Include

To use this procedure, include the library:

include glcd_touch_ads7843

Parameters

  • touch_x - word out
  • touch_y - word out

Return Value

bit - Function return value

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_touch_ads7843.jal


ads7843_init - JALlib Procedures Help

ads7843_init JALLIB PROCEDURE

Signature

procedure ads7843_init() is

Description

Initialize the ADS7843 library.The interrupt output will be enabled.

Include

To use this procedure, include the library:

include glcd_touch_ads7843

Parameters

None

Return Value

None

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_touch_ads7843.jal


ads7843_set_screen_orientation - JALlib Procedures Help

ads7843_set_screen_orientation JALLIB PROCEDURE

Signature

procedure ads7843_set_screen_orientation(byte in orientation) is

Description

Set the touch screen orientation using the screen rotation constants. The
orientation of the touch screen must match the orientation of the display.

Include

To use this procedure, include the library:

include glcd_touch_ads7843

Parameters

  • orientation - byte in

Return Value

None

Example

From sample file: 16f18857_touch_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. Three items are shown:
--              1) Touch screen calibration. It does not do an actual calibration
--                 but shows the values that can be used to re-calibrate the
--                 touch screen.
--              2) Showing the touch screen coordinates when touched and the
--                 screen pixel coordindate that belong to the touch location.
--              3) Drawing pixels when the touch screen is touched. It will show
--                 for four differnt screen rotations.
--
-- Notes:       -
--
include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_8x12_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Button constants in pixels used on display.
const word button_x_start = 100
const word button_y_start = 270
const word button_x_end = 140
const word button_y_end = 290

--  -------------------- Procedures and Functions -----------------------------

-- Draw a a simple rectangular button with the text 'DONE' in it.
procedure draw_button() is

   var word old_pen_color, old_background_color

   old_pen_color = glcd_pen_color
   old_background_color = glcd_background_color
   glcd_pen_color = ILI9341_RED
   glcd_background_color = ILI9341_RED
   glcd_box_fill(button_x_start, button_y_start,
                 button_x_end, button_y_end)
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(button_x_start + 5, button_y_start + 5)
   print_string(glcd, "DONE")
   glcd_pen_color = old_pen_color
   glcd_background_color = old_background_color

end procedure

-- Wait until the touch screen is touched and return TRUE if the
-- screen was touched in the button area on the display.
function button_touched() return bit is

   var word x_touch, y_touch,  x_pixel, y_pixel

      if ads7843_get_touch_coordinate(x_touch, y_touch) then
         ads7843_touch_to_display_coordinate(x_touch, y_touch, x_pixel, y_pixel)
         return  (x_pixel >= button_x_start) & (x_pixel <= button_x_end) &
                 (y_pixel >= button_y_start) &  (y_pixel <= button_y_end)
      else
         return FALSE
      end if

end function

-- Handle one touch on the screen indicated by a filled green box
-- and return the x and y coordinates. Change the color of the box
-- to red when the touch screen has been touched.
procedure get_coordinates_from_box(word in start_x, word in start_y,
                                   word in end_x, word in end_y,
                                   word out x, word out y) is

   var word x_in, y_in

   glcd_pen_color = ILI9341_GREEN
   -- Draw the box and wait for the screen to be touched.
   glcd_box_fill(start_x, start_y, end_x, end_y)
   while !ads7843_get_touch_coordinate(x_in, y_in) loop
      -- Waiting ...
   end loop
   x = x_in
   y = y_in
   -- Pressed, change color of box and wait for release.
   glcd_pen_color = ILI9341_RED
   glcd_box_fill(start_x, start_y, end_x, end_y)
   _usec_delay(250_000)  -- Touch 'debounce'.
   while ads7843_get_touch_coordinate(x_in, y_in) loop
      -- Waiting ...
   end loop
   -- Clear box.
   glcd_pen_color = ILI9341_BLACK
   glcd_box_fill(start_x, start_y, end_x, end_y)
   _usec_delay(250_000) -- Touch 'debounce'.

end procedure

-- Obtain the touch values of the corners of the touch screen. Use a small
-- green box in the top left corner and after touch in the bottom right corner
-- and show the touch cormer values. These values can be use to re-calibrate
-- the touch screen using the ADS7843_X_TOP_LEFT and other constants.
procedure calibrate_touch_screen() is

   var word x1, y1, x2, y2
   var word width, height

   width = glcd_display_x_size - 1
   height = glcd_display_y_size - 1
   glcd_clear_screen()
   glcd_pen_color = ILI9341_WHITE
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,40)
   print_string(glcd,"CALIBRATION")
   ili9341_goto(80,60)
   print_string(glcd,"===========")
   ili9341_goto(40,100)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"TOUCH THE GREEN BOXES")
   ili9341_goto(10,120)
   print_string(glcd,"(TOP LEFT AND BOTTOM RIGHT)")
   -- Top left.
   get_coordinates_from_box(0, 0, 5, 5, x1, y1)
   -- Bottom right.
   get_coordinates_from_box(width - 5, height - 5, width, height, x2, y2)
   -- Print coordinates.
   glcd_pen_color = ILI9341_YELLOW
   ili9341_goto(40,140)
   print_string(glcd,"X TOP LEFT: 0x")
   print_word_hex(glcd, x1)
   ili9341_goto(40,155)
   print_string(glcd,"Y TOP LEFT: 0x")
   print_word_hex(glcd, y1)
   ili9341_goto(40,170)
   print_string(glcd,"X BOTTOM RIGHT: 0x")
   print_word_hex(glcd, x2)
   ili9341_goto(40,185)
   print_string(glcd,"Y BOTTOM RIGHT: 0x")
   print_word_hex(glcd, y2)

end procedure

-- Drawing function. Read the touch screen, translate that to a display coordinate
-- and write the pixel to the display. Do this for a certain time.
procedure write_touch_pixel(word in x, word in y) is

   var word t_x, t_y, p_x, p_y
   var dword timer = 0

   ili9341_goto(x,y)
   print_string(glcd,"TOUCH THE SCREEN")
   while (timer < 6_000) loop
      if ads7843_get_touch_coordinate(t_x, t_y) then
         ads7843_touch_to_display_coordinate(t_x, t_y, p_x, p_y)
         glcd_write_pixel(p_x, p_y)
      end if
      _usec_delay(1_000)
      timer = timer + 1
   end loop

end procedure

-- --------------- Variables and start of program ----------------------------
-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y

-- Main loop starts here.
ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
ads7843_set_screen_orientation(ADS7843_ROTATE_0_DEGREES)
glcd_clear_screen()

forever  loop

    -- Start with showing the calibration figures.
   glcd_pen_color = ILI9341_WHITE
   calibrate_touch_screen()
   -- Wait for the 'DONE' button to be pressed.
   draw_button()
   while !button_touched() loop
      -- Wait for button.
   end loop

   -- Read the touch screen and show the touch screen coordinated
   -- hexadecimal and the pixel coordinates in decimal notation. Do
   -- This until the "DONE" button is pressed.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(40,40)
   print_string(glcd,"TOUCH COORDINATES")
   ili9341_goto(40,100)
   print_string(glcd,"PIXEL COORDINATES")
   glcd_pen_color = ILI9341_YELLOW
   ili9341_goto(40,60)
   print_string(glcd, "X Touch : 0x")
   ili9341_goto(40,80)
   print_string(glcd, "Y Touch : 0x")
   ili9341_goto(40,120)
   print_string(glcd, "X Pixel :")
   ili9341_goto(40,140)
   print_string(glcd, "Y Pixel :")
   draw_button()
   repeat
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         ili9341_goto(139,60)
         print_word_hex(glcd, touch_x)
         ili9341_goto(139,80)
         print_word_hex(glcd, touch_y)
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         ili9341_goto(121,120)
         print_word_dec(glcd, pixel_x)
         print_string(glcd, "    ")
         ili9341_goto(121,140)
         print_word_dec(glcd, pixel_y)
         print_string(glcd, "    ")
      end if
   until button_touched()

   -- Show the drawing function in different screen orientations.
   -- 0 degrees rotation
   glcd_clear_screen()
   glcd_pen_color = ILI9341_WHITE
   glcd_font_use(FONT_8X12)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ads7843_set_screen_orientation(ADS7843_ROTATE_0_DEGREES)
   write_touch_pixel(60,0)
   -- 90 degrees rotation
   glcd_clear_screen()
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ads7843_set_screen_orientation(ADS7843_ROTATE_90_DEGREES)
   write_touch_pixel(90,0)
   -- 180 degrees rotation
   glcd_clear_screen()
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ads7843_set_screen_orientation(ADS7843_ROTATE_180_DEGREES)
   write_touch_pixel(60,0)
   -- 270 degrees rotation
   glcd_clear_screen()
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ads7843_set_screen_orientation(ADS7843_ROTATE_270_DEGREES)
   write_touch_pixel(90,0)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ads7843_set_screen_orientation(ADS7843_ROTATE_0_DEGREES)

end loop

Generated by JALlib CHM Help System | Source: glcd_touch_ads7843.jal


ads7843_touch_to_display_coordinate - JALlib Procedures Help

ads7843_touch_to_display_coordinate JALLIB PROCEDURE

Signature

procedure ads7843_touch_to_display_coordinate(word in touch_x, word in touch_y,

Description

Convert the given touch screen coordinates to display coordinates in pixels.

Include

To use this procedure, include the library:

include glcd_touch_ads7843

Parameters

None

Return Value

None

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_touch_ads7843.jal


analog_off - JAL Language Syntax Reference

analog_off SYNTAX

Description:
-- Device include file for pic16f13145, containing: -- - Declaration of ports and pins of the chip. -- - Procedures to force the use of the LATx register -- for output when PORTx or pin_xy is addressed. -- - Symbolic definitions for configuration bits (fuses) -- - Some device dependent procedures for common -- operations, like: -- . enable_digital_io() -- -- Sources: -- - {Microchip\MPLABX V6.25 \packs\Microchip}/.../...//PIC16F13145.PIC --

Notes

-- - This file is generated by script version 2.2 -- - File creation date/time: Sat Mar 22 19:15:14 2025 -- -- ------------------------------------------------ -- const word DEVICE_ID = 0x3129 -- ID for PIC programmer const word CHIP_ID = 0xA362 -- ID in chipdef_jallib const byte PICTYPE[] = "16F13145" -- include chipdef_jallib -- common constants -- pragma target cpu PIC_14H -- (banks=64) pragma target inst 1 -- instruction set : cpu_p16f1_v1 pragma target chip 16F13145 pragma target bank 0x0080 pragma target page 0x0800 pragma stack 16 pragma code 8192 pragma ID 0x8000,4 pragma data 0x20-0x7F,0xA0-0xEF,0x120-0x16F,0x1A0-0x1EF,0x220-0x26F pragma data 0x2A0-0x2EF,0x320-0x36F,0x3A0-0x3EF,0x420-0x46F,0x4A0-0x4EF pragma data 0x520-0x56F,0x5A0-0x5EF,0x620-0x64F pragma shared 0x00-0x0B,0x70-0x7F -- var volatile byte _pic_accum at 0x7F -- (compiler) -- const word _FUSES_CT = 5 const word _FUSE_BASE[_FUSES_CT] = { 0x8007, 0x8008, 0x8009, 0x800A, 0x800B } const word _FUSES[_FUSES_CT] = { 0x3FFF, -- CONFIG1 0x3FFF, -- CONFIG2 0x3FFF, -- CONFIG3 0x3FFF, -- CONFIG4 0x3FFF -- CONFIG5 } -- -- ------------------------------------------------ var volatile byte INDF0 at { 0x0 } var volatile byte _ind at { 0x0 } -- ------------------------------------------------ var volatile byte INDF1 at { 0x1 } -- ------------------------------------------------ var volatile byte PCL at { 0x2 } var volatile byte _pcl at { 0x2 } -- ------------------------------------------------ var volatile byte STATUS at { 0x3 } var volatile bit STATUS_C at STATUS : 0 var volatile bit STATUS_DC at STATUS : 1 var volatile bit STATUS_Z at STATUS : 2 var volatile bit STATUS_NPD at STATUS : 3 var volatile bit STATUS_NTO at STATUS : 4 var volatile bit STATUS_CARRY at STATUS : 0 var volatile bit STATUS_ZERO at STATUS : 2 var volatile byte _status at { 0x3 } const byte _c = 0 const byte _dc = 1 const byte _z = 2 const byte _not_pd = 3 const byte _not_to = 4 const byte _carry = 0 const byte _zero = 2 -- ------------------------------------------------ var volatile word FSR0 at { 0x4 } var volatile word _fsr0 at { 0x4 } -- ------------------------------------------------ var volatile byte FSR0L at { 0x4 } var volatile byte _fsr0l at { 0x4 } -- ------------------------------------------------ var volatile byte FSR0H at { 0x5 } var volatile byte _fsr0h at { 0x5 } -- ------------------------------------------------ var volatile word FSR1 at { 0x6 } var volatile word _fsr1 at { 0x6 } -- ------------------------------------------------ var volatile byte FSR1L at { 0x6 } var volatile byte _fsr1l at { 0x6 } -- ------------------------------------------------ var volatile byte FSR1H at { 0x7 } var volatile byte _fsr1h at { 0x7 } -- ------------------------------------------------ var volatile byte BSR at { 0x8 } var volatile bit*6 BSR_BSR at BSR : 0 var volatile bit BSR_BSR0 at BSR : 0 var volatile bit BSR_BSR1 at BSR : 1 var volatile bit BSR_BSR2 at BSR : 2 var volatile bit BSR_BSR3 at BSR : 3 var volatile bit BSR_BSR4 at BSR : 4 var volatile bit BSR_BSR5 at BSR : 5 var volatile byte _bsr at { 0x8 } -- ------------------------------------------------ var volatile byte WREG at { 0x9 } -- ------------------------------------------------ var volatile byte PCLATH at { 0xA } var volatile bit*7 PCLATH_PCLATH at PCLATH : 0 var volatile byte _pclath at { 0xA } -- ------------------------------------------------ var volatile byte INTCON at { 0xB } var volatile bit INTCON_INTEDG at INTCON : 0 var volatile bit INTCON_PEIE at INTCON : 6 var volatile bit INTCON_GIE at INTCON : 7 -- ------------------------------------------------ var volatile byte PORTA at { 0xC } var volatile bit PORTA_RA0 at PORTA : 0 var volatile bit PORTA_RA1 at PORTA : 1 var volatile bit PORTA_RA2 at PORTA : 2 var volatile bit PORTA_RA3 at PORTA : 3 var volatile bit pin_A3 at PORTA : 3 -- var volatile bit PORTA_RA4 at PORTA : 4 var volatile bit PORTA_RA5 at PORTA : 5 -- ------------------------------------------------ var volatile byte PORTB at { 0xD } var volatile bit PORTB_RB4 at PORTB : 4 var volatile bit PORTB_RB5 at PORTB : 5 var volatile bit PORTB_RB6 at PORTB : 6 var volatile bit PORTB_RB7 at PORTB : 7 -- ------------------------------------------------ var volatile byte PORTC at { 0xE } var volatile bit PORTC_RC0 at PORTC : 0 var volatile bit PORTC_RC1 at PORTC : 1 var volatile bit PORTC_RC2 at PORTC : 2 var volatile bit PORTC_RC3 at PORTC : 3 var volatile bit PORTC_RC4 at PORTC : 4 var volatile bit PORTC_RC5 at PORTC : 5 var volatile bit PORTC_RC6 at PORTC : 6 var volatile bit PORTC_RC7 at PORTC : 7 -- ------------------------------------------------ var volatile byte TRISA at { 0x12 } alias PORTA_direction is TRISA --

Generated by JAL Syntax Documentation System | Source: DITA


arp.jal - JALLIB Library Documentation

arp.jal JALLIB LIBRARY

Title

ARP - Address Resolution Protocol BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

sends, receives and replys to ARP network packets

Sources

http://www.faqs.org/rfcs/rfc826.html
http://www.visualland.net/view.php?cid=857&protocol=ARP&title=1.%20Basic-update

Constants and Variables

arp_reply_received - var byte
arp_packet_from_destination - var bit = FALSE
ARP_HARDWARE_TYPE - const byte = 0
ARP_PROTOCOL_TYPE - const byte = 2
ARP_HARDWARE_LENGTH - const byte = 4
ARP_PROTOCOL_LENGTH - const byte = 5
ARP_OPERATION - const byte = 6
ARP_REQUEST - const byte = 1
ARP_REPLY - const byte = 2
ARP_SENDER_HARDWARE_ADDRESS_0 - const byte = 8
ARP_SENDER_HARDWARE_ADDRESS_1 - const byte = 9
ARP_SENDER_HARDWARE_ADDRESS_2 - const byte = 10
ARP_SENDER_HARDWARE_ADDRESS_3 - const byte = 11
ARP_SENDER_HARDWARE_ADDRESS_4 - const byte = 12
ARP_SENDER_HARDWARE_ADDRESS_5 - const byte = 13
ARP_SENDER_PROTOCOL_ADDRESS_0 - const byte = 14
ARP_SENDER_PROTOCOL_ADDRESS_1 - const byte = 15
ARP_SENDER_PROTOCOL_ADDRESS_2 - const byte = 16
ARP_SENDER_PROTOCOL_ADDRESS_3 - const byte = 17
ARP_TARGET_HARDWARE_ADDRESS_0 - const byte = 18
ARP_TARGET_HARDWARE_ADDRESS_1 - const byte = 19
ARP_TARGET_HARDWARE_ADDRESS_2 - const byte = 20
ARP_TARGET_HARDWARE_ADDRESS_3 - const byte = 21
ARP_TARGET_HARDWARE_ADDRESS_4 - const byte = 22
ARP_TARGET_HARDWARE_ADDRESS_5 - const byte = 23
ARP_TARGET_PROTOCOL_ADDRESS_0 - const byte = 24
ARP_TARGET_PROTOCOL_ADDRESS_1 - const byte = 25
ARP_TARGET_PROTOCOL_ADDRESS_2 - const byte = 26
ARP_TARGET_PROTOCOL_ADDRESS_3 - const byte = 27

Routines

  • arp_get_mac - Procedure
  • arp_read_packet - Procedure
  • arp_read_reply - Procedure
  • arp_send_reply - Procedure
  • arp_send_request - Procedure


arp_get_mac - JALlib Procedures Help

arp_get_mac JALLIB PROCEDURE

Signature

procedure arp_get_mac(byte in requests, word in timeout) is

Description

Get remote MAC address. Specify approx timeout in ms.

Include

To use this procedure, include the library:

include arp

Parameters

  • requests - byte in
  • timeout - word in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: arp.jal


as5600l.jal - JALLIB Library Documentation

as5600l.jal JALLIB LIBRARY

Title

Library for the AS5600 and AS5600L Magnetic Rotary Position Sensor

Author

Rob Jansen, Copyright (c) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library functions for the AS5600 and the AS5600L Magnetic
Rotary Position Sensor. The main program has to setup the IIC
communication using an IIC clock at most 1 MHz.

Notes

The library supports both the AS5600 as well as the AS5600L.
In order to select the correct device the user must provide the
the correct 7-bit IIC address in the init function. Adresses are:
-) For AS5600 = 0x37. Default address and cannot be changed.
-) For AS5600L = 0x40. Default address but this address can be changed.
Important: The library also provides burn functions which should only be used
when needed since burning cycles are limited!
This function is intially not available and can be made available
by defining:
-) const AS5600L_ENABLE_BURN = TRUE

Sources

AS5600 AMS datasheet [v1-06] 2018-Jun-20
AS5600L AMS datasheet [v1-12] 2020-May-14

============================= Public API=====================================

---------------------------- Public constants -------------------------------

Power modes.

Constants and Variables

AS5600L_POWER_MODE_NOMINAL - const byte = 0b0000_0000
AS5600L_POWER_MODE_LOW_1 - const byte = 0b0000_0001
AS5600L_POWER_MODE_LOW_2 - const byte = 0b0000_0010
AS5600L_POWER_MODE_LOW_3 - const byte = 0b0000_0011
AS5600L_HYSTERESIS_OFF - const byte = 0b0000_0000
AS5600L_HYSTERESIS_LSB_1 - const byte = 0b0000_0100
AS5600L_HYSTERESIS_LSB_2 - const byte = 0b0000_1000
AS5600L_HYSTERESIS_LSB_3 - const byte = 0b0000_1100
AS5600L_OUTPUT_STAGE_ANALOG_100 - const byte = 0b0000_0000
AS5600L_OUTPUT_STAGE_ANALOG_90 - const byte = 0b0001_0000
AS5600L_OUTPUT_STAGE_PWM - const byte = 0b0010_0000
AS5600L_PWM_115_HZ - const byte = 0b0000_0000
AS5600L_PWM_230_HZ - const byte = 0b0100_0000
AS5600L_PWM_460_HZ - const byte = 0b1000_0000
AS5600L_PWM_920_HZ - const byte = 0b1100_0000
AS5600L_SLOW_FILTER_16X - const byte = 0b0000_0000
AS5600L_SLOW_FILTER_8X - const byte = 0b0000_0001
AS5600L_SLOW_FILTER_4X - const byte = 0b0000_0010
AS5600L_SLOW_FILTER_2X - const byte = 0b0000_0011
AS5600L_FAST_FILTER_NONE - const byte = 0b0000_0000
AS5600L_FAST_FILTER_LSB_6 - const byte = 0b0000_0100
AS5600L_FAST_FILTER_LSB_7 - const byte = 0b0000_1000
AS5600L_FAST_FILTER_LSB_9 - const byte = 0b0000_1100
AS5600L_FAST_FILTER_LSB_10 - const byte = 0b0001_1100
AS5600L_FAST_FILTER_LSB_18 - const byte = 0b0001_0000
AS5600L_FAST_FILTER_LSB_21 - const byte = 0b0001_0100
AS5600L_FAST_FILTER_LSB_24 - const byte = 0b0001_1000

Routines

  • _as5600l_read_data_byte - Function returns byte
  • _as5600l_read_data_word - Function returns word
  • _as5600l_write_data_byte - Procedure
  • _as5600l_write_data_word - Procedure
  • as5600l_agc'get - Function returns byte
  • as5600l_angle_to_degree - Function returns word
  • as5600l_burn_angles - Procedure
  • as5600l_burn_settings - Procedure
  • as5600l_fast_filter'get - Function returns byte
  • as5600l_fast_filter'put - Procedure
  • as5600l_hysteresis'get - Function returns byte
  • as5600l_hysteresis'put - Procedure
  • as5600l_iic_address'get - Function returns byte
  • as5600l_iic_address'put - Procedure
  • as5600l_init - Procedure
  • as5600l_magnet_detected'get - Function returns bit
  • as5600l_magnet_too_strong'get - Function returns bit
  • as5600l_magnet_too_weak'get - Function returns bit
  • as5600l_magnitude'get - Function returns word
  • as5600l_maximum_angle'get - Function returns word
  • as5600l_maximum_angle'put - Procedure
  • as5600l_maximum_position'get - Function returns word
  • as5600l_maximum_position'put - Procedure
  • as5600l_number_of_program_cycles'get - Function returns byte
  • as5600l_output_stage'get - Function returns byte
  • as5600l_output_stage'put - Procedure
  • as5600l_power_mode'get - Function returns byte
  • as5600l_power_mode'put - Procedure
  • as5600l_pwm_frequency'get - Function returns byte
  • as5600l_pwm_frequency'put - Procedure
  • as5600l_raw_position'get - Function returns word
  • as5600l_scaled_position'get - Function returns word
  • as5600l_slow_filter'get - Function returns byte
  • as5600l_slow_filter'put - Procedure
  • as5600l_watchdog_on'get - Function returns bit
  • as5600l_watchdog_on'put - Procedure
  • as5600l_zero_position'get - Function returns word
  • as5600l_zero_position'put - Procedure


as5600l_angle_to_degree - JALlib Procedures Help

as5600l_angle_to_degree JALLIB FUNCTION

Signature

function as5600l_angle_to_degree(word in angle) return word is

Description

Convert the given angle to a degree.

Include

To use this procedure, include the library:

include as5600l

Parameters

  • angle - word in

Return Value

word - Function return value

Example

From sample file: 16f1825_as5600l.jal

-- Title: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor,
--              controlled via IIC. It demonstrates all available functions.
--              The library supports both the AS5600 as well as the AS5600L.
--              In order to select the correct device the user must provide the
--              the correct 7-bit IIC address in the init function. Adresses are:
--              -) For AS5600  = 0x37. Default address and cannot be changed.
--              -) For AS5600L = 0x40. Default address but this address can be changed.
--
-- Important:    The library also provides burn functions which should only be used
--               when needed since burning cycles are limited!
--               This function is intially not available and can be made available
--               by defining:
--               -) const AS5600L_ENABLE_BURN = TRUE
--
-- Sources: AS5600  AMS datasheet [v1-06] 2018-Jun-20
--          AS5600L AMS datasheet [v1-12] 2020-May-14
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- The AS5600 or AS5600L is selected by their 7-bit IIC address.
const byte AS5600_IIC_ADDRESS  = 0x36
const byte AS5600L_IIC_ADDRESS = 0x40
-- See the important note above. When the burning feature is used it must
-- be enabled explicitely by: const AS5600L_ENABLE_BURN = TRUE
include as5600l
as5600l_init(AS5600_IIC_ADDRESS) -- This example program uses the AS5600.

-- Variables
var word position
var byte pressed_key
var bit  burn_used = FALSE

-- Procedures

procedure clear_keyboard_buffer() is

   var byte character

   while serial_hw_read(character) loop
   end loop

end procedure

procedure wait_for_key_pressed() is

   var byte character

   while !serial_hw_read(character) loop
   end loop
   clear_keyboard_buffer()

end procedure

-- Main program starts here.
print_string(serial, "AS5600/AS5600L Magnetic Rotary Position Sensor sample program.\r\n\n")

forever  loop

   print_string(serial, "Number of program cycles used by this device: ")
   print_byte_dec(serial, as5600l_number_of_program_cycles)
   print_crlf(serial)
   print_crlf(serial)

   ; Get and store the zero position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the zero position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_zero_position = position
   print_crlf(serial)

   ; Get and store the maximum position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the maximum position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_maximum_position = position
   print_crlf(serial)

   clear_keyboard_buffer()
   print_string(serial, "Turn the magnet and check the output. Press any key to stop.\r\n")
   while !serial_hw_read(pressed_key) loop

      ; Show the current zero position en maximum position.
      print_string(serial, "Stored zero position is : ")
      print_word_dec(serial, as5600l_zero_position)
      print_crlf(serial)
      print_string(serial, "Stored maximum position is : ")
      print_word_dec(serial, as5600l_maximum_position)
      print_crlf(serial)

      ; Show the angles.
      print_string(serial, "Raw angle output: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      print_string(serial, "Raw angle in degrees: ")
      print_word_dec(serial, as5600l_angle_to_degree(position))
      print_crlf(serial)
      print_string(serial, "Scaled angle output: ")
      print_word_dec(serial, as5600l_scaled_position)
      print_crlf(serial)

      ; Indicate the status of the magnet.
      if as5600l_magnet_detected then
         print_string(serial, "Magnet detected.\r\n")
      else
         print_string(serial, "No magnet detected.\r\n")
      end if
      if as5600l_magnet_too_weak then
         print_string(serial, "Magnet is too weak.\r\n")
      end if
      if as5600l_magnet_too_strong then
         print_string(serial, "Magnet is too strong.\r\n")
      end if

      -- Show the AGC level.
      print_string(serial, "AGC level is: ")
      print_byte_dec(serial, as5600l_agc)
      print_crlf(serial)

      -- Show the magnitude level.
      print_string(serial, "Magnitude level is: ")
      print_word_dec(serial, as5600l_magnitude)
      print_crlf(serial)
      print_crlf(serial)
      delay_1s(1)

   end loop
   clear_keyboard_buffer()

   ; Show and change the power mode.
   print_string(serial, "Current power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_string(serial, "Changing power mode to: ")
   print_byte_dec(serial, AS5600L_POWER_MODE_LOW_1)
   print_crlf(serial)
   as5600l_power_mode = AS5600L_POWER_MODE_LOW_1
   print_string(serial, "New power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the hysteresis.
   print_string(serial, "Current hysteresis is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_string(serial, "Changing hystersis to: ")
   print_byte_dec(serial, AS5600L_HYSTERESIS_LSB_3)
   print_crlf(serial)
   as5600l_hysteresis = AS5600L_HYSTERESIS_LSB_3
   print_string(serial, "New hysteris is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the output stage.
   print_string(serial, "Current output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_string(serial, "Changing output stage to: ")
   print_byte_dec(serial, AS5600L_OUTPUT_STAGE_PWM)
   print_crlf(serial)
   as5600l_output_stage = AS5600L_OUTPUT_STAGE_PWM
   print_string(serial, "New output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the PWM frequency.
   print_string(serial, "Current PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_string(serial, "Changing PWM frequency to: ")
   print_byte_dec(serial, AS5600L_PWM_460_HZ)
   print_crlf(serial)
   as5600l_pwm_frequency= AS5600L_PWM_460_HZ
   print_string(serial, "New PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the slow filter.
   print_string(serial, "Current slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_string(serial, "Changing slow filter to: ")
   print_byte_dec(serial, AS5600L_SLOW_FILTER_8X)
   print_crlf(serial)
   as5600l_slow_filter = AS5600L_SLOW_FILTER_8X
   print_string(serial, "New slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the fast filter.
   print_string(serial, "Current fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_string(serial, "Changing fast filter to: ")
   print_byte_dec(serial, AS5600L_FAST_FILTER_LSB_21)
   print_crlf(serial)
   as5600l_fast_filter = AS5600L_FAST_FILTER_LSB_21
   print_string(serial, "New fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the watchdog status.
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is on, switching it off.\r\n")
      as5600l_watchdog_on = FALSE
   else
      print_string(serial, "Watchdog is off, switching it on.\r\n")
      as5600l_watchdog_on = TRUE
   end if
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is now on.\r\n")
   else
      print_string(serial, "Watchdog is now off.\r\n")
   end if
   print_crlf(serial)

   -- Change the IIC address (AS5600L only).
   if (as5600l_iic_address != AS5600_IIC_ADDRESS) then
      -- AS5600L selected, show and change current IIC address.
      print_string(serial, "Current IIC address is (AS5600L only): ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_string(serial, "Changing IIC address to: 0x70\r\n")
      print_crlf(serial)
      as5600l_iic_address = 0x70
      print_string(serial, "New IIC address is: ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_crlf(serial)
   end if

   ; Use of the burn feature. Only use when needed since this feature
   ; can only be used twice!
   if defined(AS5600L_ENABLE_BURN) then

      ; In case this is activated by accident we do it only once!
      if !burn_used then
         burn_used = TRUE ; Only do this once!!!
         print_string(serial, "Burn feature actived, only use when needed!\r\n")

         print_string(serial, "Press 'Y' if you want to burn the settings.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_settings()
            print_string(serial, "Burning settings completed.\r\n")
            print_string(serial, "If changed you have to init the library with the set IIC address.\r\n")
         else
            print_string(serial, "Burning settings skipped.\r\n")
         end if

         print_string(serial, "Press 'Y' if you want to burn the angles.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_angles()
               print_string(serial, "Burning angles completed.\r\n")
         else
            print_string(serial, "Burning angles skipped.\r\n")
         end if
      end if
      print_crlf(serial)
   end if

   print_string(serial, "Press a key to continue.\r\n")
   wait_for_key_pressed()
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: as5600l.jal


as5600l_burn_angles - JALlib Procedures Help

as5600l_burn_angles JALLIB PROCEDURE

Signature

procedure as5600l_burn_angles() is

Description

Burn the angles. These are the zero position and maximum position.

Include

To use this procedure, include the library:

include as5600l

Parameters

None

Return Value

None

Example

From sample file: 16f1825_as5600l.jal

-- Title: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor,
--              controlled via IIC. It demonstrates all available functions.
--              The library supports both the AS5600 as well as the AS5600L.
--              In order to select the correct device the user must provide the
--              the correct 7-bit IIC address in the init function. Adresses are:
--              -) For AS5600  = 0x37. Default address and cannot be changed.
--              -) For AS5600L = 0x40. Default address but this address can be changed.
--
-- Important:    The library also provides burn functions which should only be used
--               when needed since burning cycles are limited!
--               This function is intially not available and can be made available
--               by defining:
--               -) const AS5600L_ENABLE_BURN = TRUE
--
-- Sources: AS5600  AMS datasheet [v1-06] 2018-Jun-20
--          AS5600L AMS datasheet [v1-12] 2020-May-14
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- The AS5600 or AS5600L is selected by their 7-bit IIC address.
const byte AS5600_IIC_ADDRESS  = 0x36
const byte AS5600L_IIC_ADDRESS = 0x40
-- See the important note above. When the burning feature is used it must
-- be enabled explicitely by: const AS5600L_ENABLE_BURN = TRUE
include as5600l
as5600l_init(AS5600_IIC_ADDRESS) -- This example program uses the AS5600.

-- Variables
var word position
var byte pressed_key
var bit  burn_used = FALSE

-- Procedures

procedure clear_keyboard_buffer() is

   var byte character

   while serial_hw_read(character) loop
   end loop

end procedure

procedure wait_for_key_pressed() is

   var byte character

   while !serial_hw_read(character) loop
   end loop
   clear_keyboard_buffer()

end procedure

-- Main program starts here.
print_string(serial, "AS5600/AS5600L Magnetic Rotary Position Sensor sample program.\r\n\n")

forever  loop

   print_string(serial, "Number of program cycles used by this device: ")
   print_byte_dec(serial, as5600l_number_of_program_cycles)
   print_crlf(serial)
   print_crlf(serial)

   ; Get and store the zero position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the zero position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_zero_position = position
   print_crlf(serial)

   ; Get and store the maximum position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the maximum position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_maximum_position = position
   print_crlf(serial)

   clear_keyboard_buffer()
   print_string(serial, "Turn the magnet and check the output. Press any key to stop.\r\n")
   while !serial_hw_read(pressed_key) loop

      ; Show the current zero position en maximum position.
      print_string(serial, "Stored zero position is : ")
      print_word_dec(serial, as5600l_zero_position)
      print_crlf(serial)
      print_string(serial, "Stored maximum position is : ")
      print_word_dec(serial, as5600l_maximum_position)
      print_crlf(serial)

      ; Show the angles.
      print_string(serial, "Raw angle output: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      print_string(serial, "Raw angle in degrees: ")
      print_word_dec(serial, as5600l_angle_to_degree(position))
      print_crlf(serial)
      print_string(serial, "Scaled angle output: ")
      print_word_dec(serial, as5600l_scaled_position)
      print_crlf(serial)

      ; Indicate the status of the magnet.
      if as5600l_magnet_detected then
         print_string(serial, "Magnet detected.\r\n")
      else
         print_string(serial, "No magnet detected.\r\n")
      end if
      if as5600l_magnet_too_weak then
         print_string(serial, "Magnet is too weak.\r\n")
      end if
      if as5600l_magnet_too_strong then
         print_string(serial, "Magnet is too strong.\r\n")
      end if

      -- Show the AGC level.
      print_string(serial, "AGC level is: ")
      print_byte_dec(serial, as5600l_agc)
      print_crlf(serial)

      -- Show the magnitude level.
      print_string(serial, "Magnitude level is: ")
      print_word_dec(serial, as5600l_magnitude)
      print_crlf(serial)
      print_crlf(serial)
      delay_1s(1)

   end loop
   clear_keyboard_buffer()

   ; Show and change the power mode.
   print_string(serial, "Current power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_string(serial, "Changing power mode to: ")
   print_byte_dec(serial, AS5600L_POWER_MODE_LOW_1)
   print_crlf(serial)
   as5600l_power_mode = AS5600L_POWER_MODE_LOW_1
   print_string(serial, "New power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the hysteresis.
   print_string(serial, "Current hysteresis is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_string(serial, "Changing hystersis to: ")
   print_byte_dec(serial, AS5600L_HYSTERESIS_LSB_3)
   print_crlf(serial)
   as5600l_hysteresis = AS5600L_HYSTERESIS_LSB_3
   print_string(serial, "New hysteris is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the output stage.
   print_string(serial, "Current output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_string(serial, "Changing output stage to: ")
   print_byte_dec(serial, AS5600L_OUTPUT_STAGE_PWM)
   print_crlf(serial)
   as5600l_output_stage = AS5600L_OUTPUT_STAGE_PWM
   print_string(serial, "New output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the PWM frequency.
   print_string(serial, "Current PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_string(serial, "Changing PWM frequency to: ")
   print_byte_dec(serial, AS5600L_PWM_460_HZ)
   print_crlf(serial)
   as5600l_pwm_frequency= AS5600L_PWM_460_HZ
   print_string(serial, "New PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the slow filter.
   print_string(serial, "Current slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_string(serial, "Changing slow filter to: ")
   print_byte_dec(serial, AS5600L_SLOW_FILTER_8X)
   print_crlf(serial)
   as5600l_slow_filter = AS5600L_SLOW_FILTER_8X
   print_string(serial, "New slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the fast filter.
   print_string(serial, "Current fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_string(serial, "Changing fast filter to: ")
   print_byte_dec(serial, AS5600L_FAST_FILTER_LSB_21)
   print_crlf(serial)
   as5600l_fast_filter = AS5600L_FAST_FILTER_LSB_21
   print_string(serial, "New fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the watchdog status.
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is on, switching it off.\r\n")
      as5600l_watchdog_on = FALSE
   else
      print_string(serial, "Watchdog is off, switching it on.\r\n")
      as5600l_watchdog_on = TRUE
   end if
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is now on.\r\n")
   else
      print_string(serial, "Watchdog is now off.\r\n")
   end if
   print_crlf(serial)

   -- Change the IIC address (AS5600L only).
   if (as5600l_iic_address != AS5600_IIC_ADDRESS) then
      -- AS5600L selected, show and change current IIC address.
      print_string(serial, "Current IIC address is (AS5600L only): ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_string(serial, "Changing IIC address to: 0x70\r\n")
      print_crlf(serial)
      as5600l_iic_address = 0x70
      print_string(serial, "New IIC address is: ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_crlf(serial)
   end if

   ; Use of the burn feature. Only use when needed since this feature
   ; can only be used twice!
   if defined(AS5600L_ENABLE_BURN) then

      ; In case this is activated by accident we do it only once!
      if !burn_used then
         burn_used = TRUE ; Only do this once!!!
         print_string(serial, "Burn feature actived, only use when needed!\r\n")

         print_string(serial, "Press 'Y' if you want to burn the settings.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_settings()
            print_string(serial, "Burning settings completed.\r\n")
            print_string(serial, "If changed you have to init the library with the set IIC address.\r\n")
         else
            print_string(serial, "Burning settings skipped.\r\n")
         end if

         print_string(serial, "Press 'Y' if you want to burn the angles.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_angles()
               print_string(serial, "Burning angles completed.\r\n")
         else
            print_string(serial, "Burning angles skipped.\r\n")
         end if
      end if
      print_crlf(serial)
   end if

   print_string(serial, "Press a key to continue.\r\n")
   wait_for_key_pressed()
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: as5600l.jal


as5600l_burn_settings - JALlib Procedures Help

as5600l_burn_settings JALLIB PROCEDURE

Signature

procedure as5600l_burn_settings() is

Description

Burn the settings. These are the Magnitude, Configuration and IIC address.
Note that Magnitude can only be written if the zero position and maximum
positions are not yet written.

Include

To use this procedure, include the library:

include as5600l

Parameters

None

Return Value

None

Example

From sample file: 16f1825_as5600l.jal

-- Title: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor,
--              controlled via IIC. It demonstrates all available functions.
--              The library supports both the AS5600 as well as the AS5600L.
--              In order to select the correct device the user must provide the
--              the correct 7-bit IIC address in the init function. Adresses are:
--              -) For AS5600  = 0x37. Default address and cannot be changed.
--              -) For AS5600L = 0x40. Default address but this address can be changed.
--
-- Important:    The library also provides burn functions which should only be used
--               when needed since burning cycles are limited!
--               This function is intially not available and can be made available
--               by defining:
--               -) const AS5600L_ENABLE_BURN = TRUE
--
-- Sources: AS5600  AMS datasheet [v1-06] 2018-Jun-20
--          AS5600L AMS datasheet [v1-12] 2020-May-14
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- The AS5600 or AS5600L is selected by their 7-bit IIC address.
const byte AS5600_IIC_ADDRESS  = 0x36
const byte AS5600L_IIC_ADDRESS = 0x40
-- See the important note above. When the burning feature is used it must
-- be enabled explicitely by: const AS5600L_ENABLE_BURN = TRUE
include as5600l
as5600l_init(AS5600_IIC_ADDRESS) -- This example program uses the AS5600.

-- Variables
var word position
var byte pressed_key
var bit  burn_used = FALSE

-- Procedures

procedure clear_keyboard_buffer() is

   var byte character

   while serial_hw_read(character) loop
   end loop

end procedure

procedure wait_for_key_pressed() is

   var byte character

   while !serial_hw_read(character) loop
   end loop
   clear_keyboard_buffer()

end procedure

-- Main program starts here.
print_string(serial, "AS5600/AS5600L Magnetic Rotary Position Sensor sample program.\r\n\n")

forever  loop

   print_string(serial, "Number of program cycles used by this device: ")
   print_byte_dec(serial, as5600l_number_of_program_cycles)
   print_crlf(serial)
   print_crlf(serial)

   ; Get and store the zero position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the zero position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_zero_position = position
   print_crlf(serial)

   ; Get and store the maximum position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the maximum position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_maximum_position = position
   print_crlf(serial)

   clear_keyboard_buffer()
   print_string(serial, "Turn the magnet and check the output. Press any key to stop.\r\n")
   while !serial_hw_read(pressed_key) loop

      ; Show the current zero position en maximum position.
      print_string(serial, "Stored zero position is : ")
      print_word_dec(serial, as5600l_zero_position)
      print_crlf(serial)
      print_string(serial, "Stored maximum position is : ")
      print_word_dec(serial, as5600l_maximum_position)
      print_crlf(serial)

      ; Show the angles.
      print_string(serial, "Raw angle output: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      print_string(serial, "Raw angle in degrees: ")
      print_word_dec(serial, as5600l_angle_to_degree(position))
      print_crlf(serial)
      print_string(serial, "Scaled angle output: ")
      print_word_dec(serial, as5600l_scaled_position)
      print_crlf(serial)

      ; Indicate the status of the magnet.
      if as5600l_magnet_detected then
         print_string(serial, "Magnet detected.\r\n")
      else
         print_string(serial, "No magnet detected.\r\n")
      end if
      if as5600l_magnet_too_weak then
         print_string(serial, "Magnet is too weak.\r\n")
      end if
      if as5600l_magnet_too_strong then
         print_string(serial, "Magnet is too strong.\r\n")
      end if

      -- Show the AGC level.
      print_string(serial, "AGC level is: ")
      print_byte_dec(serial, as5600l_agc)
      print_crlf(serial)

      -- Show the magnitude level.
      print_string(serial, "Magnitude level is: ")
      print_word_dec(serial, as5600l_magnitude)
      print_crlf(serial)
      print_crlf(serial)
      delay_1s(1)

   end loop
   clear_keyboard_buffer()

   ; Show and change the power mode.
   print_string(serial, "Current power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_string(serial, "Changing power mode to: ")
   print_byte_dec(serial, AS5600L_POWER_MODE_LOW_1)
   print_crlf(serial)
   as5600l_power_mode = AS5600L_POWER_MODE_LOW_1
   print_string(serial, "New power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the hysteresis.
   print_string(serial, "Current hysteresis is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_string(serial, "Changing hystersis to: ")
   print_byte_dec(serial, AS5600L_HYSTERESIS_LSB_3)
   print_crlf(serial)
   as5600l_hysteresis = AS5600L_HYSTERESIS_LSB_3
   print_string(serial, "New hysteris is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the output stage.
   print_string(serial, "Current output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_string(serial, "Changing output stage to: ")
   print_byte_dec(serial, AS5600L_OUTPUT_STAGE_PWM)
   print_crlf(serial)
   as5600l_output_stage = AS5600L_OUTPUT_STAGE_PWM
   print_string(serial, "New output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the PWM frequency.
   print_string(serial, "Current PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_string(serial, "Changing PWM frequency to: ")
   print_byte_dec(serial, AS5600L_PWM_460_HZ)
   print_crlf(serial)
   as5600l_pwm_frequency= AS5600L_PWM_460_HZ
   print_string(serial, "New PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the slow filter.
   print_string(serial, "Current slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_string(serial, "Changing slow filter to: ")
   print_byte_dec(serial, AS5600L_SLOW_FILTER_8X)
   print_crlf(serial)
   as5600l_slow_filter = AS5600L_SLOW_FILTER_8X
   print_string(serial, "New slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the fast filter.
   print_string(serial, "Current fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_string(serial, "Changing fast filter to: ")
   print_byte_dec(serial, AS5600L_FAST_FILTER_LSB_21)
   print_crlf(serial)
   as5600l_fast_filter = AS5600L_FAST_FILTER_LSB_21
   print_string(serial, "New fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the watchdog status.
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is on, switching it off.\r\n")
      as5600l_watchdog_on = FALSE
   else
      print_string(serial, "Watchdog is off, switching it on.\r\n")
      as5600l_watchdog_on = TRUE
   end if
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is now on.\r\n")
   else
      print_string(serial, "Watchdog is now off.\r\n")
   end if
   print_crlf(serial)

   -- Change the IIC address (AS5600L only).
   if (as5600l_iic_address != AS5600_IIC_ADDRESS) then
      -- AS5600L selected, show and change current IIC address.
      print_string(serial, "Current IIC address is (AS5600L only): ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_string(serial, "Changing IIC address to: 0x70\r\n")
      print_crlf(serial)
      as5600l_iic_address = 0x70
      print_string(serial, "New IIC address is: ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_crlf(serial)
   end if

   ; Use of the burn feature. Only use when needed since this feature
   ; can only be used twice!
   if defined(AS5600L_ENABLE_BURN) then

      ; In case this is activated by accident we do it only once!
      if !burn_used then
         burn_used = TRUE ; Only do this once!!!
         print_string(serial, "Burn feature actived, only use when needed!\r\n")

         print_string(serial, "Press 'Y' if you want to burn the settings.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_settings()
            print_string(serial, "Burning settings completed.\r\n")
            print_string(serial, "If changed you have to init the library with the set IIC address.\r\n")
         else
            print_string(serial, "Burning settings skipped.\r\n")
         end if

         print_string(serial, "Press 'Y' if you want to burn the angles.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_angles()
               print_string(serial, "Burning angles completed.\r\n")
         else
            print_string(serial, "Burning angles skipped.\r\n")
         end if
      end if
      print_crlf(serial)
   end if

   print_string(serial, "Press a key to continue.\r\n")
   wait_for_key_pressed()
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: as5600l.jal


as5600l_init - JALlib Procedures Help

as5600l_init JALLIB PROCEDURE

Signature

procedure as5600l_init(byte in iic_address) is

Description

Init the AS5600(L) library. This sets the 7-bit IIC address with determines
which device (AS5600 or AS5600L) is selected.

Include

To use this procedure, include the library:

include as5600l

Parameters

  • iic_address - byte in

Return Value

None

Example

From sample file: 16f1825_as5600l.jal

-- Title: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the AS5600/AS5600L Magnetic Rotary Position Sensor,
--              controlled via IIC. It demonstrates all available functions.
--              The library supports both the AS5600 as well as the AS5600L.
--              In order to select the correct device the user must provide the
--              the correct 7-bit IIC address in the init function. Adresses are:
--              -) For AS5600  = 0x37. Default address and cannot be changed.
--              -) For AS5600L = 0x40. Default address but this address can be changed.
--
-- Important:    The library also provides burn functions which should only be used
--               when needed since burning cycles are limited!
--               This function is intially not available and can be made available
--               by defining:
--               -) const AS5600L_ENABLE_BURN = TRUE
--
-- Sources: AS5600  AMS datasheet [v1-06] 2018-Jun-20
--          AS5600L AMS datasheet [v1-12] 2020-May-14
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- The AS5600 or AS5600L is selected by their 7-bit IIC address.
const byte AS5600_IIC_ADDRESS  = 0x36
const byte AS5600L_IIC_ADDRESS = 0x40
-- See the important note above. When the burning feature is used it must
-- be enabled explicitely by: const AS5600L_ENABLE_BURN = TRUE
include as5600l
as5600l_init(AS5600_IIC_ADDRESS) -- This example program uses the AS5600.

-- Variables
var word position
var byte pressed_key
var bit  burn_used = FALSE

-- Procedures

procedure clear_keyboard_buffer() is

   var byte character

   while serial_hw_read(character) loop
   end loop

end procedure

procedure wait_for_key_pressed() is

   var byte character

   while !serial_hw_read(character) loop
   end loop
   clear_keyboard_buffer()

end procedure

-- Main program starts here.
print_string(serial, "AS5600/AS5600L Magnetic Rotary Position Sensor sample program.\r\n\n")

forever  loop

   print_string(serial, "Number of program cycles used by this device: ")
   print_byte_dec(serial, as5600l_number_of_program_cycles)
   print_crlf(serial)
   print_crlf(serial)

   ; Get and store the zero position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the zero position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_zero_position = position
   print_crlf(serial)

   ; Get and store the maximum position.
   clear_keyboard_buffer()
   while !serial_hw_read(pressed_key) loop
      print_string(serial, "Set the magnet in the maximum position and press a key. Current raw angle is: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      delay_1s(1)
   end loop
   as5600l_maximum_position = position
   print_crlf(serial)

   clear_keyboard_buffer()
   print_string(serial, "Turn the magnet and check the output. Press any key to stop.\r\n")
   while !serial_hw_read(pressed_key) loop

      ; Show the current zero position en maximum position.
      print_string(serial, "Stored zero position is : ")
      print_word_dec(serial, as5600l_zero_position)
      print_crlf(serial)
      print_string(serial, "Stored maximum position is : ")
      print_word_dec(serial, as5600l_maximum_position)
      print_crlf(serial)

      ; Show the angles.
      print_string(serial, "Raw angle output: ")
      position = as5600l_raw_position
      print_word_dec(serial, position)
      print_crlf(serial)
      print_string(serial, "Raw angle in degrees: ")
      print_word_dec(serial, as5600l_angle_to_degree(position))
      print_crlf(serial)
      print_string(serial, "Scaled angle output: ")
      print_word_dec(serial, as5600l_scaled_position)
      print_crlf(serial)

      ; Indicate the status of the magnet.
      if as5600l_magnet_detected then
         print_string(serial, "Magnet detected.\r\n")
      else
         print_string(serial, "No magnet detected.\r\n")
      end if
      if as5600l_magnet_too_weak then
         print_string(serial, "Magnet is too weak.\r\n")
      end if
      if as5600l_magnet_too_strong then
         print_string(serial, "Magnet is too strong.\r\n")
      end if

      -- Show the AGC level.
      print_string(serial, "AGC level is: ")
      print_byte_dec(serial, as5600l_agc)
      print_crlf(serial)

      -- Show the magnitude level.
      print_string(serial, "Magnitude level is: ")
      print_word_dec(serial, as5600l_magnitude)
      print_crlf(serial)
      print_crlf(serial)
      delay_1s(1)

   end loop
   clear_keyboard_buffer()

   ; Show and change the power mode.
   print_string(serial, "Current power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_string(serial, "Changing power mode to: ")
   print_byte_dec(serial, AS5600L_POWER_MODE_LOW_1)
   print_crlf(serial)
   as5600l_power_mode = AS5600L_POWER_MODE_LOW_1
   print_string(serial, "New power mode is: ")
   print_byte_dec(serial, as5600l_power_mode)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the hysteresis.
   print_string(serial, "Current hysteresis is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_string(serial, "Changing hystersis to: ")
   print_byte_dec(serial, AS5600L_HYSTERESIS_LSB_3)
   print_crlf(serial)
   as5600l_hysteresis = AS5600L_HYSTERESIS_LSB_3
   print_string(serial, "New hysteris is: ")
   print_byte_dec(serial, as5600l_hysteresis)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the output stage.
   print_string(serial, "Current output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_string(serial, "Changing output stage to: ")
   print_byte_dec(serial, AS5600L_OUTPUT_STAGE_PWM)
   print_crlf(serial)
   as5600l_output_stage = AS5600L_OUTPUT_STAGE_PWM
   print_string(serial, "New output stage is: ")
   print_byte_dec(serial, as5600l_output_stage)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the PWM frequency.
   print_string(serial, "Current PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_string(serial, "Changing PWM frequency to: ")
   print_byte_dec(serial, AS5600L_PWM_460_HZ)
   print_crlf(serial)
   as5600l_pwm_frequency= AS5600L_PWM_460_HZ
   print_string(serial, "New PWM frequency is: ")
   print_byte_dec(serial, as5600l_pwm_frequency)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the slow filter.
   print_string(serial, "Current slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_string(serial, "Changing slow filter to: ")
   print_byte_dec(serial, AS5600L_SLOW_FILTER_8X)
   print_crlf(serial)
   as5600l_slow_filter = AS5600L_SLOW_FILTER_8X
   print_string(serial, "New slow filter is: ")
   print_byte_dec(serial, as5600l_slow_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the fast filter.
   print_string(serial, "Current fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_string(serial, "Changing fast filter to: ")
   print_byte_dec(serial, AS5600L_FAST_FILTER_LSB_21)
   print_crlf(serial)
   as5600l_fast_filter = AS5600L_FAST_FILTER_LSB_21
   print_string(serial, "New fast filter is: ")
   print_byte_dec(serial, as5600l_fast_filter)
   print_crlf(serial)
   print_crlf(serial)

   -- Show and change the watchdog status.
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is on, switching it off.\r\n")
      as5600l_watchdog_on = FALSE
   else
      print_string(serial, "Watchdog is off, switching it on.\r\n")
      as5600l_watchdog_on = TRUE
   end if
   if as5600l_watchdog_on then
      print_string(serial, "Watchdog is now on.\r\n")
   else
      print_string(serial, "Watchdog is now off.\r\n")
   end if
   print_crlf(serial)

   -- Change the IIC address (AS5600L only).
   if (as5600l_iic_address != AS5600_IIC_ADDRESS) then
      -- AS5600L selected, show and change current IIC address.
      print_string(serial, "Current IIC address is (AS5600L only): ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_string(serial, "Changing IIC address to: 0x70\r\n")
      print_crlf(serial)
      as5600l_iic_address = 0x70
      print_string(serial, "New IIC address is: ")
      print_byte_dec(serial, as5600l_iic_address)
      print_crlf(serial)
      print_crlf(serial)
   end if

   ; Use of the burn feature. Only use when needed since this feature
   ; can only be used twice!
   if defined(AS5600L_ENABLE_BURN) then

      ; In case this is activated by accident we do it only once!
      if !burn_used then
         burn_used = TRUE ; Only do this once!!!
         print_string(serial, "Burn feature actived, only use when needed!\r\n")

         print_string(serial, "Press 'Y' if you want to burn the settings.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_settings()
            print_string(serial, "Burning settings completed.\r\n")
            print_string(serial, "If changed you have to init the library with the set IIC address.\r\n")
         else
            print_string(serial, "Burning settings skipped.\r\n")
         end if

         print_string(serial, "Press 'Y' if you want to burn the angles.\r\n")
         while !serial_hw_read(pressed_key) loop end loop
         if (pressed_key == "Y") then
            as5600l_burn_angles()
               print_string(serial, "Burning angles completed.\r\n")
         else
            print_string(serial, "Burning angles skipped.\r\n")
         end if
      end if
      print_crlf(serial)
   end if

   print_string(serial, "Press a key to continue.\r\n")
   wait_for_key_pressed()
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: as5600l.jal


ascii_to_can - JALlib Procedures Help

ascii_to_can JALLIB FUNCTION

Signature

function ascii_to_can(byte in ascii_buf[32], dword out can_id, byte out can_data[8], byte out data_len) return bit is

Description

convert ASCII message to CAN message, as per socket-CAN SLCAN API
FIXME: poor method.

Include

To use this procedure, include the library:

include can_ascii

Parameters

  • ascii_buf[] - byte in
  • can_id - dword out
  • can_data[] - byte out
  • data_len - byte out

Return Value

bit - Function return value

Example

From sample file: 18f2585_can_serial_hw.jal

-- Title: CAN to UART adapter example
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: gateway between RS232 and CAN bus. Uses ASCII encapsulation,
--          compatible with the Socket-CAN SLCAN API.
--
-- Sources: Socket-CAN, in particular the SLCAN API. http://developer.berlios.de/projects/socketcan/
--          also, the LAWICEL CAN-USB adapter.
--
-- For this example, the UART is only running at 9600. You may wish to increase to 115200 and re-test.
--
-- This file has been generated by hand (manually maintained)
--

include 18f2585
pragma target clock 16_000_000
pragma target OSC  HS_PLL
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

enable_digital_io()

var bit led is pin_A0
pin_A0_direction =  output

const usart_hw_serial = true
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- 125K bps
can_set_config(3, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- match all msgs
can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;
CANCON = 0; -- normal mode

-- gateway loop

var byte s_rxcnt, s_rxbuf[32]
var byte s_txcnt, s_txbuf[32]
s_rxcnt = 0

forever loop
   var bit got_msg, txstat
   var byte i, data_len, c
   var byte can_data[8]
   var dword can_id

   got_msg = can_receive(1, can_id, can_data, data_len)

   if got_msg then
      s_txcnt = can_to_ascii(can_id, can_data, data_len, s_txbuf)
      for s_txcnt using i loop
         serial_hw_data = s_txbuf[i]
      end loop
      -- serial_hw_data = 10
   end if

   if serial_hw_read(c) then
      s_rxbuf[s_rxcnt] = c
      s_rxcnt = s_rxcnt + 1
      if s_rxcnt >= 32 then
         s_rxcnt = 0
      end if
      if c == 13 then
         if ascii_to_can(s_rxbuf, can_id, can_data, data_len) then
            -- FIXME: should retry can_send if busy
            txstat = can_send(0, can_id, can_data, data_len)
         end if
         s_rxcnt = 0
      end if
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_ascii.jal


Assembly - JAL Language Syntax Reference

Assembly JALV2 SYNTAX

Syntax

ASM ...

Description

When all else fails, one can resort to inline assembly. This can be in the form of a single statement: or an entire block: Using assembly should be a last resort -- it is needed only when either a feature is not possible using JALv2 (for example, the TRIS and OPTION codes), or when speed is of the essence. JALv2 includes the entire assembly language set in the PIC16F87x data sheet, several instructions from earlier micro controllers, and several common macros. There is some support for the 16 bit keywords. To guarantee the correct data bank is selected when accessing a file register, use one of the following: Or: The former takes the file register from the command, the later takes it directly. Similarly, to guarantee the correct page bits are set (for GOTO or CALL), use one of the following: Or: Again, the former takes the label from the command, the later takes it directly. Normally, the codes to set or clear the bank or page bits are only generated when necessary. If the bits are already in the correct states, no further commands are generated. If you need to guarantee the codes are always generated, use the following pragmas: The former will keep any page bits, the later and bank bits. These affect the entire sub-program in which they are declared. To declare a local label for use in CALLs and/or GOTOs: Once declared, a label is inserted into the assembly block by making it the first part of a statement, followed by a ':': The available opcodes are listed below. For a full description see the appropriate data sheet. Note that when using inline assembly you should not modify the bank or page registers, FSR, or BSR. If these are modified, it is the programmers responsibility to return them to their original states.

                  ASSEMBLER

          BANK opcode ...
          BANK f
          PAGE opcode ...
          PAGE lbl
          PRAGMA KEEP PAGE
          PRAGMA KEEP BANK
                  LOCAL

          identifier: opcode...

Generated by JAL Syntax Documentation System | Source: DITA


Available Op-codes - JAL Language Syntax Reference

Available Op-codes JALV2 SYNTAX

Description

The following abbreviations are used: Note that not all opcodes are available on all devices. Check the datasheet for a complete description.

Generated by JAL Syntax Documentation System | Source: DITA


beep.jal - JALLIB Library Documentation

beep.jal JALLIB LIBRARY

Title

beep.jal

Author

Eur van Andel Copyright (c) 2009, all rights reserved.

Compiler

>=2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

simple Piezo beeper routines for different sound frequencies
all procedures sound the beeper for 1 second

Notes

--
**************************************************************************
**************************************************************************
***** *****
***** In your user code you must define two output pins: *****
***** var bit beep1 is pin_xx *****
***** pin_xx_direction is output *****
***** var bit beep2 is pin_yy *****
***** pin_yy_direction is output *****
***** *****
**************************************************************************
**************************************************************************

Routines

  • beep_1khz - Procedure
  • beep_2khz - Procedure
  • beep_4khz - Procedure
  • beep_500hz - Procedure


big_calendar.jal - JALLIB Library Documentation

big_calendar.jal JALLIB LIBRARY

Title

Universal gregorian calendar routines

Author

Oliver "Kiste" Seitz, Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

The hardware RTCC present in some PIC devices is limited to years 2000...2099.
If you want to build e.g. a time-travelling vehicle, such a clock is of little use.
This software library implements a RTCC which is valid from friday, October 15, 1582
to presumably at least the year 7000. Earlier, the julian calendar was valid. Later, the
inaccuracy of the gregorian leap year rules may have accumulated to a whole day.

Constants and Variables

bigcal_current_date - var bigcal_datetype

Routines

  • bigcal_add_days - Procedure
  • bigcal_days_per_month - Function returns byte
  • bigcal_find_easter - Procedure
  • bigcal_update_current - Procedure
  • bigcal_weekday - Function returns byte


bigcal_add_days - JALlib Procedures Help

bigcal_add_days JALLIB PROCEDURE

Signature

procedure bigcal_add_days(bigcal_datetype in out ddate, sword in distance) is

Description

Title: Alter a given date by a number of days
Arguments: - Year
- Month
- Day
- distance
Returns: A modified date (year,month,day)
Notes: distance can be positive, moves date to the future
distance can be negative, moves date to the past
+/-32768 days is a bit more than 89 years

Include

To use this procedure, include the library:

include big_calendar

Parameters

  • ddate - bigcal_datetype in out
  • distance - sword in

Return Value

None

Example

From sample file: 16f688_big_calendar.jal

-- ------------------------------------------------------
-- Title: Calendar demo
--
-- Author: Oliver "Kiste" Seitz  Copyright (c) 2012, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Demonstration program for Microchip PIC16f688 using big_calendar.jal
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f688                    -- target PICmicro
--
-- This program assumes that an external oscillator generates a
-- 20 MHz signal which is connected to pin OSC1.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      EC_NOCLKOUT               -- external clock
pragma target WDT      disabled     -- no watchdog
pragma target MCLR     internal     -- no reset pin
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

include big_calendar

var byte*3 timer_counts = 0

procedure timer1_isr() is
  pragma interrupt

  if PIR1_TMR1IF == true then

    PIR1_TMR1IF=false

    timer_counts=timer_counts+65536

    if timer_counts > ( target_clock / 32 ) then -- 32 = 4*8, 4= Fosc/Fc; 8=prescaler value

      timer_counts=timer_counts-( target_clock / 32 )
      bigcal_current_time.second = bigcal_current_time.second + 1

    end if

  end if

end procedure

include delay

const serial_hw_baudrate=9600
include serial_hardware

serial_hw_init

alias serial_data is serial_hw_data

include print

bigcal_current_date.year=2009
bigcal_current_date.month=12
bigcal_current_date.day=31

procedure print_date() is

  print_crlf(serial_data)

  const byte string_sun[]="   Sunday"
  const byte string_mon[]="   Monday"
  const byte string_tue[]="  Tuesday"
  const byte string_wed[]="Wednesday"
  const byte string_thu[]=" Thursday"
  const byte string_fri[]="   Friday"
  const byte string_sat[]=" Saturday"

   case bigcal_weekday(bigcal_current_date) of
      0:print_string(serial_data,string_sun)
      1:print_string(serial_data,string_mon)
      2:print_string(serial_data,string_tue)
      3:print_string(serial_data,string_wed)
      4:print_string(serial_data,string_thu)
      5:print_string(serial_data,string_fri)
      6:print_string(serial_data,string_sat)
   end case

   const byte string_jan[]="  January"
   const byte string_feb[]=" February"
   const byte string_mar[]="    March"
   const byte string_apr[]="    April"
   const byte string_may[]="      May"
   const byte string_jun[]="     June"
   const byte string_jul[]="     July"
   const byte string_aug[]="   August"
   const byte string_sep[]="September"
   const byte string_oct[]="  October"
   const byte string_nov[]=" November"
   const byte string_dec[]=" December"  -- Wouldn't it be nice to have 2-dimensional constant arrays...? ;-)

   serial_data=","
   serial_data=" "

   case bigcal_current_date.month of
      1:print_string(serial_data,string_jan)
      2:print_string(serial_data,string_feb)
      3:print_string(serial_data,string_mar)
      4:print_string(serial_data,string_apr)
      5:print_string(serial_data,string_may)
      6:print_string(serial_data,string_jun)
      7:print_string(serial_data,string_jul)
      8:print_string(serial_data,string_aug)
      9:print_string(serial_data,string_sep)
     10:print_string(serial_data,string_oct)
     11:print_string(serial_data,string_nov)
     12:print_string(serial_data,string_dec)
   end case

   serial_data=" "
   print_byte_dec(serial_data,bigcal_current_date.day)
   serial_data="."
   print_word_dec(serial_data,bigcal_current_date.year)

end procedure

delay_1s(5)

print_date

print_sword_dec(serial_data,-30000)
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,-30000)
print_date()

serial_data="+"
serial_data="6"
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,6)
print_date()

for 30 loop

   serial_data="+"
   print_word_dec(serial_data,1000)
   print_crlf(serial_data)

   bigcal_add_days(bigcal_current_date,1000)
   print_date()

end loop

print_crlf(serial_data)

bigcal_current_date.year=1980

for 50 loop -- display some dates for easter sunday

   bigcal_find_easter(bigcal_current_date)
   print_date()
   bigcal_add_days(bigcal_current_date,365)

end loop

delay_1s(5)

bigcal_current_date.month=10
bigcal_current_date.day=15
bigcal_current_date.year=1582
var byte day_of_week=5 -- first day of the gregorian calendar

const byte string_ok[]=": OK!"
const byte string_error[]=": ERROR!!!!"

for 10000 loop -- check a few weekday calculations

   if day_of_week != bigcal_weekday(bigcal_current_date) then
      print_crlf(serial_data)
      print_date()
      print_string(serial_data,string_error)
      print_crlf(serial_data)
      forever loop end loop  -- the program will end here on the first error.
                             -- There will be an error, at least when "year" rolls over.
   end if

   if bigcal_current_date.day==31 then
      if bigcal_current_date.month==12 then
         print_word_dec(serial_data,bigcal_current_date.year)  -- output the number of each successfully checked year
         print_string(serial_data,string_ok)
         print_crlf(serial_data)
      end if
   end if

   bigcal_add_days(bigcal_current_date,1)
   day_of_week=day_of_week+1
   if day_of_week==7 then
      day_of_week=0
   end if
end loop

-- now, run the clock normally

bigcal_current_date.year=1999
bigcal_current_date.month=12
bigcal_current_date.day=31

bigcal_current_time.hour=23
bigcal_current_time.minute=58
bigcal_current_time.second=0

TMR1=0

T1CON_TMR1GE = false	-- no gate
T1CON_T1CKPS = 3	-- 1:8 prescaler
T1CON_TMR1CS = 0	-- internal clock
T1CON_TMR1ON = 1	-- aaaaand GO!

INTCON_GIE  = true
INTCON_PEIE = true
PIR1_TMR1IF = false
PIE1_TMR1IE = true	-- enable interrupt

var byte old_second=100

forever loop

  if old_second != bigcal_current_time.second then

    bigcal_update_current()

    old_second = bigcal_current_time.second

    print_date()

    serial_data=" "
    print_byte_dec(serial_data,bigcal_current_time.hour)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.minute)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.second)

  end if

end loop

Generated by JALlib CHM Help System | Source: big_calendar.jal


bigcal_find_easter - JALlib Procedures Help

bigcal_find_easter JALLIB PROCEDURE

Signature

procedure bigcal_find_easter(bigcal_datetype in out edate) is

Description

Title: Find date of easter sunday
Arguments: year in datetype record
Returns: complete datetype record with date of easter sunday
Notes: Calculates the date of easter sunday using formulae
created by C.F. Gauss, modified by Dr. H. Lichtenberg
as published by the german date and time authority
"Physikalisch-Technische Bundesanstalt".

Include

To use this procedure, include the library:

include big_calendar

Parameters

  • edate - bigcal_datetype in out

Return Value

None

Example

From sample file: 16f688_big_calendar.jal

-- ------------------------------------------------------
-- Title: Calendar demo
--
-- Author: Oliver "Kiste" Seitz  Copyright (c) 2012, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Demonstration program for Microchip PIC16f688 using big_calendar.jal
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f688                    -- target PICmicro
--
-- This program assumes that an external oscillator generates a
-- 20 MHz signal which is connected to pin OSC1.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      EC_NOCLKOUT               -- external clock
pragma target WDT      disabled     -- no watchdog
pragma target MCLR     internal     -- no reset pin
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

include big_calendar

var byte*3 timer_counts = 0

procedure timer1_isr() is
  pragma interrupt

  if PIR1_TMR1IF == true then

    PIR1_TMR1IF=false

    timer_counts=timer_counts+65536

    if timer_counts > ( target_clock / 32 ) then -- 32 = 4*8, 4= Fosc/Fc; 8=prescaler value

      timer_counts=timer_counts-( target_clock / 32 )
      bigcal_current_time.second = bigcal_current_time.second + 1

    end if

  end if

end procedure

include delay

const serial_hw_baudrate=9600
include serial_hardware

serial_hw_init

alias serial_data is serial_hw_data

include print

bigcal_current_date.year=2009
bigcal_current_date.month=12
bigcal_current_date.day=31

procedure print_date() is

  print_crlf(serial_data)

  const byte string_sun[]="   Sunday"
  const byte string_mon[]="   Monday"
  const byte string_tue[]="  Tuesday"
  const byte string_wed[]="Wednesday"
  const byte string_thu[]=" Thursday"
  const byte string_fri[]="   Friday"
  const byte string_sat[]=" Saturday"

   case bigcal_weekday(bigcal_current_date) of
      0:print_string(serial_data,string_sun)
      1:print_string(serial_data,string_mon)
      2:print_string(serial_data,string_tue)
      3:print_string(serial_data,string_wed)
      4:print_string(serial_data,string_thu)
      5:print_string(serial_data,string_fri)
      6:print_string(serial_data,string_sat)
   end case

   const byte string_jan[]="  January"
   const byte string_feb[]=" February"
   const byte string_mar[]="    March"
   const byte string_apr[]="    April"
   const byte string_may[]="      May"
   const byte string_jun[]="     June"
   const byte string_jul[]="     July"
   const byte string_aug[]="   August"
   const byte string_sep[]="September"
   const byte string_oct[]="  October"
   const byte string_nov[]=" November"
   const byte string_dec[]=" December"  -- Wouldn't it be nice to have 2-dimensional constant arrays...? ;-)

   serial_data=","
   serial_data=" "

   case bigcal_current_date.month of
      1:print_string(serial_data,string_jan)
      2:print_string(serial_data,string_feb)
      3:print_string(serial_data,string_mar)
      4:print_string(serial_data,string_apr)
      5:print_string(serial_data,string_may)
      6:print_string(serial_data,string_jun)
      7:print_string(serial_data,string_jul)
      8:print_string(serial_data,string_aug)
      9:print_string(serial_data,string_sep)
     10:print_string(serial_data,string_oct)
     11:print_string(serial_data,string_nov)
     12:print_string(serial_data,string_dec)
   end case

   serial_data=" "
   print_byte_dec(serial_data,bigcal_current_date.day)
   serial_data="."
   print_word_dec(serial_data,bigcal_current_date.year)

end procedure

delay_1s(5)

print_date

print_sword_dec(serial_data,-30000)
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,-30000)
print_date()

serial_data="+"
serial_data="6"
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,6)
print_date()

for 30 loop

   serial_data="+"
   print_word_dec(serial_data,1000)
   print_crlf(serial_data)

   bigcal_add_days(bigcal_current_date,1000)
   print_date()

end loop

print_crlf(serial_data)

bigcal_current_date.year=1980

for 50 loop -- display some dates for easter sunday

   bigcal_find_easter(bigcal_current_date)
   print_date()
   bigcal_add_days(bigcal_current_date,365)

end loop

delay_1s(5)

bigcal_current_date.month=10
bigcal_current_date.day=15
bigcal_current_date.year=1582
var byte day_of_week=5 -- first day of the gregorian calendar

const byte string_ok[]=": OK!"
const byte string_error[]=": ERROR!!!!"

for 10000 loop -- check a few weekday calculations

   if day_of_week != bigcal_weekday(bigcal_current_date) then
      print_crlf(serial_data)
      print_date()
      print_string(serial_data,string_error)
      print_crlf(serial_data)
      forever loop end loop  -- the program will end here on the first error.
                             -- There will be an error, at least when "year" rolls over.
   end if

   if bigcal_current_date.day==31 then
      if bigcal_current_date.month==12 then
         print_word_dec(serial_data,bigcal_current_date.year)  -- output the number of each successfully checked year
         print_string(serial_data,string_ok)
         print_crlf(serial_data)
      end if
   end if

   bigcal_add_days(bigcal_current_date,1)
   day_of_week=day_of_week+1
   if day_of_week==7 then
      day_of_week=0
   end if
end loop

-- now, run the clock normally

bigcal_current_date.year=1999
bigcal_current_date.month=12
bigcal_current_date.day=31

bigcal_current_time.hour=23
bigcal_current_time.minute=58
bigcal_current_time.second=0

TMR1=0

T1CON_TMR1GE = false	-- no gate
T1CON_T1CKPS = 3	-- 1:8 prescaler
T1CON_TMR1CS = 0	-- internal clock
T1CON_TMR1ON = 1	-- aaaaand GO!

INTCON_GIE  = true
INTCON_PEIE = true
PIR1_TMR1IF = false
PIE1_TMR1IE = true	-- enable interrupt

var byte old_second=100

forever loop

  if old_second != bigcal_current_time.second then

    bigcal_update_current()

    old_second = bigcal_current_time.second

    print_date()

    serial_data=" "
    print_byte_dec(serial_data,bigcal_current_time.hour)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.minute)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.second)

  end if

end loop

Generated by JALlib CHM Help System | Source: big_calendar.jal


bigcal_update_current - JALlib Procedures Help

bigcal_update_current JALLIB PROCEDURE

Signature

procedure bigcal_update_current() is

Description

Title: Update current time and date
Arguments: none
Returns: none
Notes: works on global variables current_date and current_time.
"current_time.seconds" is to be updated somehow, e.g. a timer or the like.
This procedure updates all the other variables, depending on the
rising value of "current_time.seconds".
It should be called regularly. Once a second is ok, but not stricktly
necessary. "seconds" should not overflow, so this procedure must
be called at least once every four minutes.

Include

To use this procedure, include the library:

include big_calendar

Parameters

None

Return Value

None

Example

From sample file: 16f688_big_calendar.jal

-- ------------------------------------------------------
-- Title: Calendar demo
--
-- Author: Oliver "Kiste" Seitz  Copyright (c) 2012, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Demonstration program for Microchip PIC16f688 using big_calendar.jal
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f688                    -- target PICmicro
--
-- This program assumes that an external oscillator generates a
-- 20 MHz signal which is connected to pin OSC1.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      EC_NOCLKOUT               -- external clock
pragma target WDT      disabled     -- no watchdog
pragma target MCLR     internal     -- no reset pin
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

include big_calendar

var byte*3 timer_counts = 0

procedure timer1_isr() is
  pragma interrupt

  if PIR1_TMR1IF == true then

    PIR1_TMR1IF=false

    timer_counts=timer_counts+65536

    if timer_counts > ( target_clock / 32 ) then -- 32 = 4*8, 4= Fosc/Fc; 8=prescaler value

      timer_counts=timer_counts-( target_clock / 32 )
      bigcal_current_time.second = bigcal_current_time.second + 1

    end if

  end if

end procedure

include delay

const serial_hw_baudrate=9600
include serial_hardware

serial_hw_init

alias serial_data is serial_hw_data

include print

bigcal_current_date.year=2009
bigcal_current_date.month=12
bigcal_current_date.day=31

procedure print_date() is

  print_crlf(serial_data)

  const byte string_sun[]="   Sunday"
  const byte string_mon[]="   Monday"
  const byte string_tue[]="  Tuesday"
  const byte string_wed[]="Wednesday"
  const byte string_thu[]=" Thursday"
  const byte string_fri[]="   Friday"
  const byte string_sat[]=" Saturday"

   case bigcal_weekday(bigcal_current_date) of
      0:print_string(serial_data,string_sun)
      1:print_string(serial_data,string_mon)
      2:print_string(serial_data,string_tue)
      3:print_string(serial_data,string_wed)
      4:print_string(serial_data,string_thu)
      5:print_string(serial_data,string_fri)
      6:print_string(serial_data,string_sat)
   end case

   const byte string_jan[]="  January"
   const byte string_feb[]=" February"
   const byte string_mar[]="    March"
   const byte string_apr[]="    April"
   const byte string_may[]="      May"
   const byte string_jun[]="     June"
   const byte string_jul[]="     July"
   const byte string_aug[]="   August"
   const byte string_sep[]="September"
   const byte string_oct[]="  October"
   const byte string_nov[]=" November"
   const byte string_dec[]=" December"  -- Wouldn't it be nice to have 2-dimensional constant arrays...? ;-)

   serial_data=","
   serial_data=" "

   case bigcal_current_date.month of
      1:print_string(serial_data,string_jan)
      2:print_string(serial_data,string_feb)
      3:print_string(serial_data,string_mar)
      4:print_string(serial_data,string_apr)
      5:print_string(serial_data,string_may)
      6:print_string(serial_data,string_jun)
      7:print_string(serial_data,string_jul)
      8:print_string(serial_data,string_aug)
      9:print_string(serial_data,string_sep)
     10:print_string(serial_data,string_oct)
     11:print_string(serial_data,string_nov)
     12:print_string(serial_data,string_dec)
   end case

   serial_data=" "
   print_byte_dec(serial_data,bigcal_current_date.day)
   serial_data="."
   print_word_dec(serial_data,bigcal_current_date.year)

end procedure

delay_1s(5)

print_date

print_sword_dec(serial_data,-30000)
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,-30000)
print_date()

serial_data="+"
serial_data="6"
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,6)
print_date()

for 30 loop

   serial_data="+"
   print_word_dec(serial_data,1000)
   print_crlf(serial_data)

   bigcal_add_days(bigcal_current_date,1000)
   print_date()

end loop

print_crlf(serial_data)

bigcal_current_date.year=1980

for 50 loop -- display some dates for easter sunday

   bigcal_find_easter(bigcal_current_date)
   print_date()
   bigcal_add_days(bigcal_current_date,365)

end loop

delay_1s(5)

bigcal_current_date.month=10
bigcal_current_date.day=15
bigcal_current_date.year=1582
var byte day_of_week=5 -- first day of the gregorian calendar

const byte string_ok[]=": OK!"
const byte string_error[]=": ERROR!!!!"

for 10000 loop -- check a few weekday calculations

   if day_of_week != bigcal_weekday(bigcal_current_date) then
      print_crlf(serial_data)
      print_date()
      print_string(serial_data,string_error)
      print_crlf(serial_data)
      forever loop end loop  -- the program will end here on the first error.
                             -- There will be an error, at least when "year" rolls over.
   end if

   if bigcal_current_date.day==31 then
      if bigcal_current_date.month==12 then
         print_word_dec(serial_data,bigcal_current_date.year)  -- output the number of each successfully checked year
         print_string(serial_data,string_ok)
         print_crlf(serial_data)
      end if
   end if

   bigcal_add_days(bigcal_current_date,1)
   day_of_week=day_of_week+1
   if day_of_week==7 then
      day_of_week=0
   end if
end loop

-- now, run the clock normally

bigcal_current_date.year=1999
bigcal_current_date.month=12
bigcal_current_date.day=31

bigcal_current_time.hour=23
bigcal_current_time.minute=58
bigcal_current_time.second=0

TMR1=0

T1CON_TMR1GE = false	-- no gate
T1CON_T1CKPS = 3	-- 1:8 prescaler
T1CON_TMR1CS = 0	-- internal clock
T1CON_TMR1ON = 1	-- aaaaand GO!

INTCON_GIE  = true
INTCON_PEIE = true
PIR1_TMR1IF = false
PIE1_TMR1IE = true	-- enable interrupt

var byte old_second=100

forever loop

  if old_second != bigcal_current_time.second then

    bigcal_update_current()

    old_second = bigcal_current_time.second

    print_date()

    serial_data=" "
    print_byte_dec(serial_data,bigcal_current_time.hour)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.minute)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.second)

  end if

end loop

Generated by JALlib CHM Help System | Source: big_calendar.jal


bigcal_weekday - JALlib Procedures Help

bigcal_weekday JALLIB FUNCTION

Signature

function bigcal_weekday(bigcal_datetype in ddate) return byte is

Description

Title: Weekday
Arguments: - Year (from 1582 up)
- Month (1 to 12)
- Day (1 to 31)
Returns: Weekday of the given date (0=sunday, 1=monday...)
Notes: Based on "Zeller's congruence"

Include

To use this procedure, include the library:

include big_calendar

Parameters

  • ddate - bigcal_datetype in

Return Value

byte - Weekday of the given date (0=sunday, 1=monday...)

Example

From sample file: 16f688_big_calendar.jal

-- ------------------------------------------------------
-- Title: Calendar demo
--
-- Author: Oliver "Kiste" Seitz  Copyright (c) 2012, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Demonstration program for Microchip PIC16f688 using big_calendar.jal
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f688                    -- target PICmicro
--
-- This program assumes that an external oscillator generates a
-- 20 MHz signal which is connected to pin OSC1.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      EC_NOCLKOUT               -- external clock
pragma target WDT      disabled     -- no watchdog
pragma target MCLR     internal     -- no reset pin
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

include big_calendar

var byte*3 timer_counts = 0

procedure timer1_isr() is
  pragma interrupt

  if PIR1_TMR1IF == true then

    PIR1_TMR1IF=false

    timer_counts=timer_counts+65536

    if timer_counts > ( target_clock / 32 ) then -- 32 = 4*8, 4= Fosc/Fc; 8=prescaler value

      timer_counts=timer_counts-( target_clock / 32 )
      bigcal_current_time.second = bigcal_current_time.second + 1

    end if

  end if

end procedure

include delay

const serial_hw_baudrate=9600
include serial_hardware

serial_hw_init

alias serial_data is serial_hw_data

include print

bigcal_current_date.year=2009
bigcal_current_date.month=12
bigcal_current_date.day=31

procedure print_date() is

  print_crlf(serial_data)

  const byte string_sun[]="   Sunday"
  const byte string_mon[]="   Monday"
  const byte string_tue[]="  Tuesday"
  const byte string_wed[]="Wednesday"
  const byte string_thu[]=" Thursday"
  const byte string_fri[]="   Friday"
  const byte string_sat[]=" Saturday"

   case bigcal_weekday(bigcal_current_date) of
      0:print_string(serial_data,string_sun)
      1:print_string(serial_data,string_mon)
      2:print_string(serial_data,string_tue)
      3:print_string(serial_data,string_wed)
      4:print_string(serial_data,string_thu)
      5:print_string(serial_data,string_fri)
      6:print_string(serial_data,string_sat)
   end case

   const byte string_jan[]="  January"
   const byte string_feb[]=" February"
   const byte string_mar[]="    March"
   const byte string_apr[]="    April"
   const byte string_may[]="      May"
   const byte string_jun[]="     June"
   const byte string_jul[]="     July"
   const byte string_aug[]="   August"
   const byte string_sep[]="September"
   const byte string_oct[]="  October"
   const byte string_nov[]=" November"
   const byte string_dec[]=" December"  -- Wouldn't it be nice to have 2-dimensional constant arrays...? ;-)

   serial_data=","
   serial_data=" "

   case bigcal_current_date.month of
      1:print_string(serial_data,string_jan)
      2:print_string(serial_data,string_feb)
      3:print_string(serial_data,string_mar)
      4:print_string(serial_data,string_apr)
      5:print_string(serial_data,string_may)
      6:print_string(serial_data,string_jun)
      7:print_string(serial_data,string_jul)
      8:print_string(serial_data,string_aug)
      9:print_string(serial_data,string_sep)
     10:print_string(serial_data,string_oct)
     11:print_string(serial_data,string_nov)
     12:print_string(serial_data,string_dec)
   end case

   serial_data=" "
   print_byte_dec(serial_data,bigcal_current_date.day)
   serial_data="."
   print_word_dec(serial_data,bigcal_current_date.year)

end procedure

delay_1s(5)

print_date

print_sword_dec(serial_data,-30000)
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,-30000)
print_date()

serial_data="+"
serial_data="6"
print_crlf(serial_data)

bigcal_add_days(bigcal_current_date,6)
print_date()

for 30 loop

   serial_data="+"
   print_word_dec(serial_data,1000)
   print_crlf(serial_data)

   bigcal_add_days(bigcal_current_date,1000)
   print_date()

end loop

print_crlf(serial_data)

bigcal_current_date.year=1980

for 50 loop -- display some dates for easter sunday

   bigcal_find_easter(bigcal_current_date)
   print_date()
   bigcal_add_days(bigcal_current_date,365)

end loop

delay_1s(5)

bigcal_current_date.month=10
bigcal_current_date.day=15
bigcal_current_date.year=1582
var byte day_of_week=5 -- first day of the gregorian calendar

const byte string_ok[]=": OK!"
const byte string_error[]=": ERROR!!!!"

for 10000 loop -- check a few weekday calculations

   if day_of_week != bigcal_weekday(bigcal_current_date) then
      print_crlf(serial_data)
      print_date()
      print_string(serial_data,string_error)
      print_crlf(serial_data)
      forever loop end loop  -- the program will end here on the first error.
                             -- There will be an error, at least when "year" rolls over.
   end if

   if bigcal_current_date.day==31 then
      if bigcal_current_date.month==12 then
         print_word_dec(serial_data,bigcal_current_date.year)  -- output the number of each successfully checked year
         print_string(serial_data,string_ok)
         print_crlf(serial_data)
      end if
   end if

   bigcal_add_days(bigcal_current_date,1)
   day_of_week=day_of_week+1
   if day_of_week==7 then
      day_of_week=0
   end if
end loop

-- now, run the clock normally

bigcal_current_date.year=1999
bigcal_current_date.month=12
bigcal_current_date.day=31

bigcal_current_time.hour=23
bigcal_current_time.minute=58
bigcal_current_time.second=0

TMR1=0

T1CON_TMR1GE = false	-- no gate
T1CON_T1CKPS = 3	-- 1:8 prescaler
T1CON_TMR1CS = 0	-- internal clock
T1CON_TMR1ON = 1	-- aaaaand GO!

INTCON_GIE  = true
INTCON_PEIE = true
PIR1_TMR1IF = false
PIE1_TMR1IE = true	-- enable interrupt

var byte old_second=100

forever loop

  if old_second != bigcal_current_time.second then

    bigcal_update_current()

    old_second = bigcal_current_time.second

    print_date()

    serial_data=" "
    print_byte_dec(serial_data,bigcal_current_time.hour)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.minute)
    serial_data=":"
    print_byte_dec(serial_data,bigcal_current_time.second)

  end if

end loop

Generated by JALlib CHM Help System | Source: big_calendar.jal


bit_array_1.jal - JALLIB Library Documentation

bit_array_1.jal JALLIB LIBRARY

Title

bit array library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library allows creation of bit arrays with
up to 16383 entries.

Sources

notes:
uses large_array_1 library when BIT_ARRAY_1_SIZE > 2047
const dword BIT_ARRAY_1_SIZE = 100 -- choose number of array variables
include bit_array -- include the array library
alias test is bit_array_1 -- rename/alias the array to test

create a byte array to hold the bits

Constants and Variables

LARGE_ARRAY_1_SIZE - const dword = _BIT_ARRAY_1_ARRAY_SIZE -- choose number of array variables
choose number of array variables
LARGE_ARRAY_1_VARIABLE_SIZE - const dword = 1 -- choose size of variables (byte)
choose size of variables (byte)

Routines

  • _bit_array_1_get_byte - Function returns bit
  • _bit_array_1_set_byte - Procedure
  • bit_array_1'get - Function returns bit
  • bit_array_1'put - Procedure


bluetooth_hc05.jal - JALLIB Library Documentation

bluetooth_hc05.jal JALLIB LIBRARY

Title

Library for the Bluetooth HC-05 module.

Author

Rob Jansen, Copyright (c) 2021..2021, all rights reserved., Adapted-by:

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

JAL library for use of the Bluetooth HC-05 module.
Created for HC-05 firmware version: 4.0-20190815

Notes

The default serial interface of the HC-05 is 34800 baud, 1 stopbit,
no parity and no flowcontrol.
At least one of the JAL serial hardware libraries must be included and
initialized by the main program with these settings.
It is recommended to use the JAL serial libraries that work on an
interrupt basis. These libraries make use of buffers which reduce
the chance of data loss in case the main program is slow or in case
where different baudrates are used.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFINTIONS --------------------------
-----------------------------------------------------------------------------

Definition of the size of the receive buffer. The size is mainly
determined by the number of Bluetooth devices that can be
discovered by the HC-05 when using the inquire command (+INQ).
If this number is low, the buffer can be smaller. If the a
buffer of more than 78 bytes is used, the large_array library
will be included and used.

Sources

-) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
April, 2011
-) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
Rev. 1r0

Constants and Variables

BLUETOOTH_HC05_RECEIVE_BUFFER_SIZE - const byte = 60
BLUETOOTH_HC05_MAX_INQUIRED_DEVICES - const byte = 5
BLUETOOTH_HC05_PASSWORD_MAX_LENGTH - const byte = 16
BLUETOOTH_HC05_NAME_MAX_LENGTH - const byte = 32
BLUETOOTH_HC05_BAUDRATE_4800 - const byte = 1
BLUETOOTH_HC05_BAUDRATE_9600 - const byte = 2
BLUETOOTH_HC05_BAUDRATE_19200 - const byte = 3
BLUETOOTH_HC05_BAUDRATE_38400 - const byte = 4
BLUETOOTH_HC05_BAUDRATE_57600 - const byte = 5
BLUETOOTH_HC05_BAUDRATE_115200 - const byte = 6
BLUETOOTH_HC05_BAUDRATE_230400 - const byte = 7
BLUETOOTH_HC05_BAUDRATE_460800 - const byte = 8
BLUETOOTH_HC05_BAUDRATE_921600 - const byte = 9
BLUETOOTH_HC05_BAUDRATE_1382400 - const byte = 10
BLUETOOTH_HC05_ROLE_SLAVE - const byte = 0 -- Default
Default
BLUETOOTH_HC05_ROLE_MASTER - const byte = 1
BLUETOOTH_HC05_ROLE_SLAVE_LOOP - const byte = 2
BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC - const byte = 0 -- Default
Default
BLUETOOTH_HC05_CONNECTION_MODE_ANY - const byte = 1
BLUETOOTH_HC05_CONNECTION_MODE_TEST - const byte = 2
BLUETOOTH_HC05_INQUIRY_MODE_STANDARD - const byte = 0
BLUETOOTH_HC05_INQUIRY_MODE_RSSI - const byte = 1
LARGE_ARRAY_1_SIZE - const word = BLUETOOTH_HC05_RECEIVE_BUFFER_SIZE+2
LARGE_ARRAY_1_VARIABLE_SIZE - const word = 1 -- Array of bytes.
Array of bytes.
bluetooth_hc05_bytes_received - var byte
character - var byte
index - var byte
stop - var bit
index - var byte
index - var byte = 0
done - var bit = FALSE

Routines

  • _bluetooth_hc05_ascii_to_binary - Function returns dword
  • _bluetooth_hc05_find_token - Function returns bit
  • _bluetooth_hc05_flush_serial_receive_buffer - Procedure
  • _bluetooth_hc05_get_bluetooth_address_part - Function returns dword
  • _bluetooth_hc05_get_received_byte - Function returns bit
  • _bluetooth_hc05_hex_char_to_value - Function returns byte
  • _bluetooth_hc05_is_valid_ascii_hex - Function returns bit
  • _bluetooth_hc05_parse_bluetooth_address - Procedure
  • _bluetooth_hc05_purge_receive_buffer - Procedure
  • _bluetooth_hc05_send_bluetooth_address - Procedure
  • _bluetooth_hc05_send_byte_hex - Procedure
  • _bluetooth_hc05_send_crlf - Procedure
  • _bluetooth_hc05_send_string - Procedure
  • _bluetooth_hc05_strip_crlf_from_receive_buffer - Procedure
  • _bluetooth_hc05_value_to_hex_char - Function returns byte
  • _bluetooth_hc05_wait_and_find_token - Function returns bit
  • _bluetooth_hc05_wait_and_get_data_ok - Function returns bit
  • bluetooth_hc05_available - Function returns bit
  • bluetooth_hc05_clear_all_paired_devices - Function returns bit
  • bluetooth_hc05_connect_to_device - Function returns bit
  • bluetooth_hc05_data'get - Function returns byte
  • bluetooth_hc05_data'put - Procedure
  • bluetooth_hc05_data_available - Function returns bit
  • bluetooth_hc05_data_ready - Function returns bit
  • bluetooth_hc05_get_binding_address - Function returns bit
  • bluetooth_hc05_get_bluetooth_address - Function returns bit
  • bluetooth_hc05_get_connection_mode - Function returns bit
  • bluetooth_hc05_get_device_address - Function returns bit
  • bluetooth_hc05_get_device_baudrate - Function returns bit
  • bluetooth_hc05_get_device_class - Function returns bit
  • bluetooth_hc05_get_device_name - Function returns bit
  • bluetooth_hc05_get_device_password - Function returns bit
  • bluetooth_hc05_get_device_role - Function returns bit
  • bluetooth_hc05_get_firmware_version - Function returns bit
  • bluetooth_hc05_get_inquire_access_code - Function returns bit
  • bluetooth_hc05_get_inquire_access_mode - Function returns bit
  • bluetooth_hc05_get_remote_device_name - Function returns bit
  • bluetooth_hc05_init - Function returns bit
  • bluetooth_hc05_initialize_ssp_profile - Function returns bit
  • bluetooth_hc05_pair_with_device - Function returns bit
  • bluetooth_hc05_reset - Function returns bit
  • bluetooth_hc05_restore_default - Function returns bit
  • bluetooth_hc05_send_command - Function returns bit
  • bluetooth_hc05_set_baudrate - Function returns bit
  • bluetooth_hc05_set_binding_address - Function returns bit
  • bluetooth_hc05_set_connection_mode - Function returns bit
  • bluetooth_hc05_set_device_class - Function returns bit
  • bluetooth_hc05_set_device_name - Function returns bit
  • bluetooth_hc05_set_device_password - Function returns bit
  • bluetooth_hc05_set_device_role - Function returns bit
  • bluetooth_hc05_set_inquire_access_code - Function returns bit
  • bluetooth_hc05_set_inquire_access_mode - Function returns bit
  • bluetooth_hc05_set_wait_time - Procedure


bluetooth_hc05_available - JALlib Procedures Help

bluetooth_hc05_available JALLIB FUNCTION

Signature

function bluetooth_hc05_available() return bit is

Description

Returns TRUE if the module is responding, otherwise FALSE is returned.
When the module is connected to the host the response will also be FALSE.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_clear_all_paired_devices - JALlib Procedures Help

bluetooth_hc05_clear_all_paired_devices JALLIB FUNCTION

Signature

function bluetooth_hc05_clear_all_paired_devices() return bit is

Description

Deletes all authenticated devices in the pair list.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_connect_to_device - JALlib Procedures Help

bluetooth_hc05_connect_to_device JALLIB FUNCTION

Signature

function bluetooth_hc05_connect_to_device(word in nap, byte in uap,

Description

Connect to the device with the given Bluetooth address.
The address is given in de NAP:UAP:LAP format. Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_data_available - JALlib Procedures Help

bluetooth_hc05_data_available JALLIB FUNCTION

Signature

function bluetooth_hc05_data_available() return bit is

Description

Returns TRUE if data is received from the module. Data can then be obtained
by reading from the variable 'bluetooth_hc05_data'.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_binding_address - JALlib Procedures Help

bluetooth_hc05_get_binding_address JALLIB FUNCTION

Signature

function bluetooth_hc05_get_binding_address(word out nap, byte out uap,

Description

Get the binding Bluetooth address of the connected device. The address
of the remote module is given in de NAP:UAP:LAP format.
Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_bluetooth_address - JALlib Procedures Help

bluetooth_hc05_get_bluetooth_address JALLIB FUNCTION

Signature

function bluetooth_hc05_get_bluetooth_address(word out nap, byte out uap,

Description

Get the Bluetooth address of the module. The Bluetooth device address
(BD_ADDRESS) is a 48-bit address and consists of the following parts:
*) Non-significant address part (NAP), consisting of 16 bits
*) Upper address part (UAP), consisting of 8 bits
*) Lower address part (LAP), consisting of 24 bits
Returns TRUE if succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_connection_mode - JALlib Procedures Help

bluetooth_hc05_get_connection_mode JALLIB FUNCTION

Signature

function bluetooth_hc05_get_connection_mode(byte out connection_mode) return bit is

Description

Get the connection mode. Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • connection_mode - byte out

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_device_address - JALlib Procedures Help

bluetooth_hc05_get_device_address JALLIB FUNCTION

Signature

function bluetooth_hc05_get_device_address(byte in name[], word out nap,

Description

Get the bluetooth addres of the device with the given name. This function handles
at most BLUETOOTH_HC05_MAX_INQUIRED_DEVICES responses. Returns TRUE when found.
The address is given in de NAP:UAP:LAP format.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_device_baudrate - JALlib Procedures Help

bluetooth_hc05_get_device_baudrate JALLIB FUNCTION

Signature

function bluetooth_hc05_get_device_baudrate() return bit is

Description

Get the device baudrate. Returns TRUE if succesful. The device baudrate
is returned in the bluetooth_hc05_receive_buffer.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_device_class - JALlib Procedures Help

bluetooth_hc05_get_device_class JALLIB FUNCTION

Signature

function bluetooth_hc05_get_device_class(dword out class) return bit is

Description

Get the device class and return it as dword. Returns TRUE when succesful.
The device class is a 24 bit number.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • class - dword out

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_device_name - JALlib Procedures Help

bluetooth_hc05_get_device_name JALLIB FUNCTION

Signature

function bluetooth_hc05_get_device_name() return bit is

Description

Get the device name of the module. Returns TRUE if succesful. The
device name is returned in the bluetooth_hc05_receive_buffer.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_device_password - JALlib Procedures Help

bluetooth_hc05_get_device_password JALLIB FUNCTION

Signature

function bluetooth_hc05_get_device_password() return bit is

Description

Get the device password. Returns TRUE if succesful. The device password
is returned in the bluetooth_hc05_receive_buffer.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_device_role - JALlib Procedures Help

bluetooth_hc05_get_device_role JALLIB FUNCTION

Signature

function bluetooth_hc05_get_device_role(byte out role) return bit is

Description

Get the device role. Returns TRUE if succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • role - byte out

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_firmware_version - JALlib Procedures Help

bluetooth_hc05_get_firmware_version JALLIB FUNCTION

Signature

function bluetooth_hc05_get_firmware_version() return bit is

Description

Get the firmware version number. Returns TRUE if succesful. The version
is returned in the bluetooth_hc05_receive_buffer.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_inquire_access_mode - JALlib Procedures Help

bluetooth_hc05_get_inquire_access_mode JALLIB FUNCTION

Signature

function bluetooth_hc05_get_inquire_access_mode(byte out inquire_access_mode, word out maximum_devices,

Description

Get the inquire access mode. Return values are:
*) Inquire_access_mode: 0 (standard) or 1 (rssi - default)
*) Maximum_devices: 0 to 32000 (default is 1)
*) Timeout: 1 to 48 (default is 48). Timeout * 1.28 gives timeout in seconds.
Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_get_remote_device_name - JALlib Procedures Help

bluetooth_hc05_get_remote_device_name JALLIB FUNCTION

Signature

function bluetooth_hc05_get_remote_device_name(word in nap, byte in uap,

Description

Get the device name of the remote module by sending the address. The address
of the remote module is given in de NAP:UAP:LAP format. The remote device
name is returned in the bluetooth_hc05_receive_buffer. Returns TRUE if succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_init - JALlib Procedures Help

bluetooth_hc05_init JALLIB FUNCTION

Signature

function bluetooth_hc05_init() return bit is

Description

Initialize (reset) the module. The wait time is set to 1 second.
Returns TRUE if succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_initialize_ssp_profile - JALlib Procedures Help

bluetooth_hc05_initialize_ssp_profile JALLIB FUNCTION

Signature

function bluetooth_hc05_initialize_ssp_profile() return bit is

Description

Initialize the SSP profile.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_pair_with_device - JALlib Procedures Help

bluetooth_hc05_pair_with_device JALLIB FUNCTION

Signature

function bluetooth_hc05_pair_with_device(word in nap, byte in uap,

Description

Pair with the remote Bluetooth device using the given address.The address
of the remote module is given in de NAP:UAP:LAP format.
Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_reset - JALlib Procedures Help

bluetooth_hc05_reset JALLIB FUNCTION

Signature

function bluetooth_hc05_reset() return bit is

Description

Resets the bluetooth module.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_restore_default - JALlib Procedures Help

bluetooth_hc05_restore_default JALLIB FUNCTION

Signature

function bluetooth_hc05_restore_default() return bit is

Description

Restore the device to the factory defaults. Returns TRUE when succcesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_baudrate - JALlib Procedures Help

bluetooth_hc05_set_baudrate JALLIB FUNCTION

Signature

function bluetooth_hc05_set_baudrate(byte in baudrate) return bit is

Description

Set the baudrate of the module and the baudrate of the serial interface
connected to the module. Returns TRUE when succesful. Baudrate is set
to 1 stop bit, no parity.
Note: The baudrate changes after a new power up of the module. Make sure
that the baudrate of the PIC is also changed to this new baudrate
after power up.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • baudrate - byte in

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_binding_address - JALlib Procedures Help

bluetooth_hc05_set_binding_address JALLIB FUNCTION

Signature

function bluetooth_hc05_set_binding_address(word in nap, byte in uap,

Description

Set the binding Bluetooth address of the device to connect to.
The address is given in de NAP:UAP:LAP format. Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_connection_mode - JALlib Procedures Help

bluetooth_hc05_set_connection_mode JALLIB FUNCTION

Signature

function bluetooth_hc05_set_connection_mode(byte in connection_mode) return bit is

Description

Set the connection mode. If the mode BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC
is used, the actual Bleutooth device address must be set by the function
bluetooth_hc05_set_binding_bluetooth_address(). Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • connection_mode - byte in

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_device_class - JALlib Procedures Help

bluetooth_hc05_set_device_class JALLIB FUNCTION

Signature

function bluetooth_hc05_set_device_class(dword in class) return bit is

Description

Set the device class. Returns TRUE when succesful. The device class
is a 24 bit number.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • class - dword in

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_device_name - JALlib Procedures Help

bluetooth_hc05_set_device_name JALLIB FUNCTION

Signature

function bluetooth_hc05_set_device_name(byte in name[]) return bit is

Description

Set the device name. The device name may not be longer than
BLUETOOTH_HC05_NAME_MAX_LENGTH. Returns TRUE when succcesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • name[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_device_password - JALlib Procedures Help

bluetooth_hc05_set_device_password JALLIB FUNCTION

Signature

function bluetooth_hc05_set_device_password(byte in password[]) return bit is

Description

Set the device password. The password may not be longer than
BLUETOOTH_HC05_PASSWORD_MAX_LENGTH. Returns TRUE when succesful.
The default factory password is "1234".

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • password[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_device_role - JALlib Procedures Help

bluetooth_hc05_set_device_role JALLIB FUNCTION

Signature

function bluetooth_hc05_set_device_role(byte in role) return bit is

Description

Set the role of the device. Return TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • role - byte in

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_inquire_access_mode - JALlib Procedures Help

bluetooth_hc05_set_inquire_access_mode JALLIB FUNCTION

Signature

function bluetooth_hc05_set_inquire_access_mode(byte in inquire_access_mode, word in maximum_devices,

Description

Set the inquire access mode. Values of paramters are:
*) Inquire_access_mode: 0 (standard) or 1 (rssi - default)
*) Maximum_devices: 0 to 32000 (default is 1)
*) Timeout: 1 to 48 (default is 48). Timeout * 1.28 gives timeout in seconds.
Returns TRUE when succesful.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

None

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc05_set_wait_time - JALlib Procedures Help

bluetooth_hc05_set_wait_time JALLIB PROCEDURE

Signature

procedure bluetooth_hc05_set_wait_time(dword in waittime) is

Description

Set the wait time for the HC-05 to respond. Time is set in 100 us times.

Include

To use this procedure, include the library:

include bluetooth_hc05

Parameters

  • waittime - dword in

Return Value

None

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: bluetooth_hc05.jal


bluetooth_hc06.jal - JALLIB Library Documentation

bluetooth_hc06.jal JALLIB LIBRARY

Title

Library for the Bluetooth HC-06 module.

Author

Rob Jansen, Copyright (c) 2021..2021, all rights reserved., Adapted-by:

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

JAL library for use of the Bluetooth HC-06 module.

Notes

The default serial interface of the HC-06 is 9600 baud, 1 stopbit,
no parity and no flowcontrol.
At least one of the JAL serial hardware libraries must be included and
initialized by the main program with these settings.
This library was tested with HC-06 firmware version: DX_Smartv2.0
A read timeout is used for the module to respond. This timeout is
can be set in steps of 100 us can be overruled by defining:
- const word BT_HC06_READ_TIMEOUT = 5_000 -- 0.5 seconds (default).
It is recommended to use the JAL serial libraries that work on an
interrupt basis. These libraries make use of buffers which reduce
the chance of data loss in case the main program is slow or in case
where different baudrates are used.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFINTIONS --------------------------
-----------------------------------------------------------------------------

Maximum wait time to receive data from the module. The read timeout can
be overruled by the main program. Timeout is in steps of 100 us.

Sources

Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
Guangzhou HC Information Technology Co., Ltd.

Constants and Variables

BLUETOOTH_HC06_READ_TIMEOUT - const word = 5_000 -- 0.5 second (default).
0.5 second (default).
BLUETOOTH_HC06_BAUDRATE_1200 - const byte = 1 -- Not supported by FW DX_Smartv2.0
Not supported by FW DX_Smartv2.0
BLUETOOTH_HC06_BAUDRATE_2400 - const byte = 2
BLUETOOTH_HC06_BAUDRATE_4800 - const byte = 3
BLUETOOTH_HC06_BAUDRATE_9600 - const byte = 4
BLUETOOTH_HC06_BAUDRATE_19200 - const byte = 5
BLUETOOTH_HC06_BAUDRATE_38400 - const byte = 6
BLUETOOTH_HC06_BAUDRATE_57600 - const byte = 7
BLUETOOTH_HC06_BAUDRATE_115200 - const byte = 8
BLUETOOTH_HC06_BAUDRATE_230400 - const byte = 9 -- Not supported by FW DX_Smartv2.0
Not supported by FW DX_Smartv2.0

Routines

  • _bluetooth_hc06_acknowledge - Function returns bit
  • _bluetooth_hc06_flush_serial_receive_buffer - Procedure
  • _bluetooth_hc06_send_string - Procedure
  • _bluetooth_hc06_wait_and_parse_response - Function returns bit
  • bluetooth_hc06_available - Function returns bit
  • bluetooth_hc06_data'get - Function returns byte
  • bluetooth_hc06_data'put - Procedure
  • bluetooth_hc06_data_available - Function returns bit
  • bluetooth_hc06_data_ready - Function returns bit
  • bluetooth_hc06_init - Procedure
  • bluetooth_hc06_send_command - Function returns bit
  • bluetooth_hc06_set_baudrate - Function returns bit
  • bluetooth_hc06_set_device_name - Function returns bit
  • bluetooth_hc06_set_device_pin - Function returns bit


bluetooth_hc06_available - JALlib Procedures Help

bluetooth_hc06_available JALLIB FUNCTION

Signature

function bluetooth_hc06_available() return bit is

Description

Returns TRUE if the module is responding, otherwise FALSE is returned.
When the module is connected to the host the response will also be FALSE.

Include

To use this procedure, include the library:

include bluetooth_hc06

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f877a_bluetooth_hc06_slave.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-06 module
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC06 slave module.
--              With this program LEDs can be controlled remotely from a host
--              and when a key is pressed it will be sent to the host. The HC-06
--              can be reprogrammed by making the 'program' pin active low.
--
-- Sources:     Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
--              Guangzhou HC Information Technology Co., Ltd.
--
-- Notes:       The HC-06 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              PIC USART connections to module (40 pin DIP):
--              *) TX: pin 25 of the USART1 of the PIC to the RX pin of the Module.
--              *) RX: pin 26 of the USART1 of the PIC to the TX pin of the Module.
--
include 16f877a

-- ------------------------------- Pragmas -------------------------------------

-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming

-- Enable weak pull-up on port B.
OPTION_REG_NRBPU = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------

-- Programming pin.
alias program_pin is pin_B1                    -- Active LOW.
pin_B1_direction = input                       -- Pin 34 for 40 pin DIP.

-- Aliases for keys.
alias key_red is pin_B2                        -- Active LOW.
pin_B2_direction = input                       -- Pin 35 of 40 pin DIP.
alias key_green is pin_B4                      -- Active LOW.
pin_B4_direction = input                       -- Pin 37 of 40 pin DIP.

-- Aliases for leds.
alias led_amber  is pin_D0                     -- On when connected.
pin_D0_direction = output                      -- Pin 19 of 40 pin DIP.
alias led_red    is pin_D1
pin_D1_direction = output                      -- Pin 20 of 40 pin DIP.
alias led_green is pin_D2
pin_D2_direction = output                      -- Pin 21 of 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate = 9600   -- Default baudrate of module.

-- It is best to use the interrupt based serial routines to prevent data loss
-- when data is received. Adjust the buffer size.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 10 -- size of receive buffer

-- Optional. Wait at most 1 second for a character from the module.
-- const word BLUETOOTH_HC06_READ_TIMEOUT = 10_000 -- 10.000 times 100 us, see library.

-- -------------------------- Includes go here ---------------------------------
include serial_hw_int_cts
include bluetooth_hc06  -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-06. Change to your needs.
const byte DEVICE_PINCODE[] = "1111"                       -- Default is "1234"
const byte DEVICE_NAME[]    = "My HC-06"
const byte DEVICE_BAUDRATE  = BLUETOOTH_HC06_BAUDRATE_9600 -- This is the default.

-- ------------------------- Variable declarations -----------------------------
var byte character
var bit  all_ok

-- -----------------------  Main program starts here ---------------------------

-- Initialize the libraries
serial_hw_init()
bluetooth_hc06_init()

-- LEDs off.
led_amber = LOW
led_red = LOW
led_green = LOW

-- Let's see if the module is available for programming.
all_ok = bluetooth_hc06_available()

-- Check the program pin, if low we will change some default values of the
-- HC-06 module but only if the module is available.
if all_ok & !program_pin then

   -- Change the pincode of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_pin(DEVICE_PINCODE)

   -- Change the name of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_name(DEVICE_NAME)

   -- Change the baudrate. Note that the baudrate changes after a new power up
   -- of the module. Make sure that the PIC also uses this new baudrate after power up.
   all_ok = all_ok &  bluetooth_hc06_set_baudrate(DEVICE_BAUDRATE)

   -- If all went OK, flash the green LED, else flash the red LED.
   if all_ok then
      -- In order to take effect we need to reset the device.
      bluetooth_hc06_reset()
      led_green = HIGH
      _usec_delay(3_000_000)
      led_green = LOW
   else
      led_red = HIGH
      _usec_delay(3_000_000)
      led_red = LOW
   end if

end if

-- We will wait for the device to be connected, that is it will no longer indicate
-- that it is available. Note that if the module is not working it will also
-- not indicate that it is available so this is not 100%. Blink the amber lED
-- while waiting. This step is just for information and can be removed since
-- there is also a LED blinking on the device that shows if the module is
-- connected or not.
while bluetooth_hc06_available() loop
   led_amber = !led_amber
   _usec_delay(500_000)
end loop

-- No longer responding may mean that we are connected.
led_amber = HIGH

-- Main loop.
forever loop

  -- Check if data is received from the Bluetooth Module to control the LEDs.
  if bluetooth_hc06_data_available() then
     character = bluetooth_hc06_data
     if (character == "R") | (character == "r") then
        led_red = !led_red
     elsif (character == "G") | (character == "g") then
        led_green = !led_green
     end if
   end if

   -- Check if we need to send a pressed key.
   if !key_red then
      bluetooth_hc06_data = "R"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if
   if !key_green then
      bluetooth_hc06_data = "G"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if

end loop

Generated by JALlib CHM Help System | Source: bluetooth_hc06.jal


bluetooth_hc06_data_available - JALlib Procedures Help

bluetooth_hc06_data_available JALLIB FUNCTION

Signature

function bluetooth_hc06_data_available() return bit is

Description

Returns TRUE if data is received from the module. Data can then be obluetoothained
by reading from the variable 'bluetooth_hc06_data'.

Include

To use this procedure, include the library:

include bluetooth_hc06

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f877a_bluetooth_hc06_slave.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-06 module
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC06 slave module.
--              With this program LEDs can be controlled remotely from a host
--              and when a key is pressed it will be sent to the host. The HC-06
--              can be reprogrammed by making the 'program' pin active low.
--
-- Sources:     Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
--              Guangzhou HC Information Technology Co., Ltd.
--
-- Notes:       The HC-06 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              PIC USART connections to module (40 pin DIP):
--              *) TX: pin 25 of the USART1 of the PIC to the RX pin of the Module.
--              *) RX: pin 26 of the USART1 of the PIC to the TX pin of the Module.
--
include 16f877a

-- ------------------------------- Pragmas -------------------------------------

-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming

-- Enable weak pull-up on port B.
OPTION_REG_NRBPU = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------

-- Programming pin.
alias program_pin is pin_B1                    -- Active LOW.
pin_B1_direction = input                       -- Pin 34 for 40 pin DIP.

-- Aliases for keys.
alias key_red is pin_B2                        -- Active LOW.
pin_B2_direction = input                       -- Pin 35 of 40 pin DIP.
alias key_green is pin_B4                      -- Active LOW.
pin_B4_direction = input                       -- Pin 37 of 40 pin DIP.

-- Aliases for leds.
alias led_amber  is pin_D0                     -- On when connected.
pin_D0_direction = output                      -- Pin 19 of 40 pin DIP.
alias led_red    is pin_D1
pin_D1_direction = output                      -- Pin 20 of 40 pin DIP.
alias led_green is pin_D2
pin_D2_direction = output                      -- Pin 21 of 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate = 9600   -- Default baudrate of module.

-- It is best to use the interrupt based serial routines to prevent data loss
-- when data is received. Adjust the buffer size.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 10 -- size of receive buffer

-- Optional. Wait at most 1 second for a character from the module.
-- const word BLUETOOTH_HC06_READ_TIMEOUT = 10_000 -- 10.000 times 100 us, see library.

-- -------------------------- Includes go here ---------------------------------
include serial_hw_int_cts
include bluetooth_hc06  -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-06. Change to your needs.
const byte DEVICE_PINCODE[] = "1111"                       -- Default is "1234"
const byte DEVICE_NAME[]    = "My HC-06"
const byte DEVICE_BAUDRATE  = BLUETOOTH_HC06_BAUDRATE_9600 -- This is the default.

-- ------------------------- Variable declarations -----------------------------
var byte character
var bit  all_ok

-- -----------------------  Main program starts here ---------------------------

-- Initialize the libraries
serial_hw_init()
bluetooth_hc06_init()

-- LEDs off.
led_amber = LOW
led_red = LOW
led_green = LOW

-- Let's see if the module is available for programming.
all_ok = bluetooth_hc06_available()

-- Check the program pin, if low we will change some default values of the
-- HC-06 module but only if the module is available.
if all_ok & !program_pin then

   -- Change the pincode of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_pin(DEVICE_PINCODE)

   -- Change the name of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_name(DEVICE_NAME)

   -- Change the baudrate. Note that the baudrate changes after a new power up
   -- of the module. Make sure that the PIC also uses this new baudrate after power up.
   all_ok = all_ok &  bluetooth_hc06_set_baudrate(DEVICE_BAUDRATE)

   -- If all went OK, flash the green LED, else flash the red LED.
   if all_ok then
      -- In order to take effect we need to reset the device.
      bluetooth_hc06_reset()
      led_green = HIGH
      _usec_delay(3_000_000)
      led_green = LOW
   else
      led_red = HIGH
      _usec_delay(3_000_000)
      led_red = LOW
   end if

end if

-- We will wait for the device to be connected, that is it will no longer indicate
-- that it is available. Note that if the module is not working it will also
-- not indicate that it is available so this is not 100%. Blink the amber lED
-- while waiting. This step is just for information and can be removed since
-- there is also a LED blinking on the device that shows if the module is
-- connected or not.
while bluetooth_hc06_available() loop
   led_amber = !led_amber
   _usec_delay(500_000)
end loop

-- No longer responding may mean that we are connected.
led_amber = HIGH

-- Main loop.
forever loop

  -- Check if data is received from the Bluetooth Module to control the LEDs.
  if bluetooth_hc06_data_available() then
     character = bluetooth_hc06_data
     if (character == "R") | (character == "r") then
        led_red = !led_red
     elsif (character == "G") | (character == "g") then
        led_green = !led_green
     end if
   end if

   -- Check if we need to send a pressed key.
   if !key_red then
      bluetooth_hc06_data = "R"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if
   if !key_green then
      bluetooth_hc06_data = "G"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if

end loop

Generated by JALlib CHM Help System | Source: bluetooth_hc06.jal


bluetooth_hc06_init - JALlib Procedures Help

bluetooth_hc06_init JALLIB PROCEDURE

Signature

procedure bluetooth_hc06_init() is

Description

Initialize the module. This is the same as resetting the module.

Include

To use this procedure, include the library:

include bluetooth_hc06

Parameters

None

Return Value

None

Example

From sample file: 16f877a_bluetooth_hc06_slave.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-06 module
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC06 slave module.
--              With this program LEDs can be controlled remotely from a host
--              and when a key is pressed it will be sent to the host. The HC-06
--              can be reprogrammed by making the 'program' pin active low.
--
-- Sources:     Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
--              Guangzhou HC Information Technology Co., Ltd.
--
-- Notes:       The HC-06 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              PIC USART connections to module (40 pin DIP):
--              *) TX: pin 25 of the USART1 of the PIC to the RX pin of the Module.
--              *) RX: pin 26 of the USART1 of the PIC to the TX pin of the Module.
--
include 16f877a

-- ------------------------------- Pragmas -------------------------------------

-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming

-- Enable weak pull-up on port B.
OPTION_REG_NRBPU = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------

-- Programming pin.
alias program_pin is pin_B1                    -- Active LOW.
pin_B1_direction = input                       -- Pin 34 for 40 pin DIP.

-- Aliases for keys.
alias key_red is pin_B2                        -- Active LOW.
pin_B2_direction = input                       -- Pin 35 of 40 pin DIP.
alias key_green is pin_B4                      -- Active LOW.
pin_B4_direction = input                       -- Pin 37 of 40 pin DIP.

-- Aliases for leds.
alias led_amber  is pin_D0                     -- On when connected.
pin_D0_direction = output                      -- Pin 19 of 40 pin DIP.
alias led_red    is pin_D1
pin_D1_direction = output                      -- Pin 20 of 40 pin DIP.
alias led_green is pin_D2
pin_D2_direction = output                      -- Pin 21 of 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate = 9600   -- Default baudrate of module.

-- It is best to use the interrupt based serial routines to prevent data loss
-- when data is received. Adjust the buffer size.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 10 -- size of receive buffer

-- Optional. Wait at most 1 second for a character from the module.
-- const word BLUETOOTH_HC06_READ_TIMEOUT = 10_000 -- 10.000 times 100 us, see library.

-- -------------------------- Includes go here ---------------------------------
include serial_hw_int_cts
include bluetooth_hc06  -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-06. Change to your needs.
const byte DEVICE_PINCODE[] = "1111"                       -- Default is "1234"
const byte DEVICE_NAME[]    = "My HC-06"
const byte DEVICE_BAUDRATE  = BLUETOOTH_HC06_BAUDRATE_9600 -- This is the default.

-- ------------------------- Variable declarations -----------------------------
var byte character
var bit  all_ok

-- -----------------------  Main program starts here ---------------------------

-- Initialize the libraries
serial_hw_init()
bluetooth_hc06_init()

-- LEDs off.
led_amber = LOW
led_red = LOW
led_green = LOW

-- Let's see if the module is available for programming.
all_ok = bluetooth_hc06_available()

-- Check the program pin, if low we will change some default values of the
-- HC-06 module but only if the module is available.
if all_ok & !program_pin then

   -- Change the pincode of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_pin(DEVICE_PINCODE)

   -- Change the name of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_name(DEVICE_NAME)

   -- Change the baudrate. Note that the baudrate changes after a new power up
   -- of the module. Make sure that the PIC also uses this new baudrate after power up.
   all_ok = all_ok &  bluetooth_hc06_set_baudrate(DEVICE_BAUDRATE)

   -- If all went OK, flash the green LED, else flash the red LED.
   if all_ok then
      -- In order to take effect we need to reset the device.
      bluetooth_hc06_reset()
      led_green = HIGH
      _usec_delay(3_000_000)
      led_green = LOW
   else
      led_red = HIGH
      _usec_delay(3_000_000)
      led_red = LOW
   end if

end if

-- We will wait for the device to be connected, that is it will no longer indicate
-- that it is available. Note that if the module is not working it will also
-- not indicate that it is available so this is not 100%. Blink the amber lED
-- while waiting. This step is just for information and can be removed since
-- there is also a LED blinking on the device that shows if the module is
-- connected or not.
while bluetooth_hc06_available() loop
   led_amber = !led_amber
   _usec_delay(500_000)
end loop

-- No longer responding may mean that we are connected.
led_amber = HIGH

-- Main loop.
forever loop

  -- Check if data is received from the Bluetooth Module to control the LEDs.
  if bluetooth_hc06_data_available() then
     character = bluetooth_hc06_data
     if (character == "R") | (character == "r") then
        led_red = !led_red
     elsif (character == "G") | (character == "g") then
        led_green = !led_green
     end if
   end if

   -- Check if we need to send a pressed key.
   if !key_red then
      bluetooth_hc06_data = "R"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if
   if !key_green then
      bluetooth_hc06_data = "G"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if

end loop

Generated by JALlib CHM Help System | Source: bluetooth_hc06.jal


bluetooth_hc06_set_baudrate - JALlib Procedures Help

bluetooth_hc06_set_baudrate JALLIB FUNCTION

Signature

function bluetooth_hc06_set_baudrate(byte in baudrate) return bit is

Description

Set the baudrate of the module and the baudrate of the serial interface
connected to the module. Returns TRUE when succesful.
Note: The baudrate changes after a new power up of the module. Make sure
that the baudrate of the PIC is also changed to this new baudrate
after power up.

Include

To use this procedure, include the library:

include bluetooth_hc06

Parameters

  • baudrate - byte in

Return Value

bit - Function return value

Example

From sample file: 16f877a_bluetooth_hc06_slave.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-06 module
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC06 slave module.
--              With this program LEDs can be controlled remotely from a host
--              and when a key is pressed it will be sent to the host. The HC-06
--              can be reprogrammed by making the 'program' pin active low.
--
-- Sources:     Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
--              Guangzhou HC Information Technology Co., Ltd.
--
-- Notes:       The HC-06 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              PIC USART connections to module (40 pin DIP):
--              *) TX: pin 25 of the USART1 of the PIC to the RX pin of the Module.
--              *) RX: pin 26 of the USART1 of the PIC to the TX pin of the Module.
--
include 16f877a

-- ------------------------------- Pragmas -------------------------------------

-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming

-- Enable weak pull-up on port B.
OPTION_REG_NRBPU = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------

-- Programming pin.
alias program_pin is pin_B1                    -- Active LOW.
pin_B1_direction = input                       -- Pin 34 for 40 pin DIP.

-- Aliases for keys.
alias key_red is pin_B2                        -- Active LOW.
pin_B2_direction = input                       -- Pin 35 of 40 pin DIP.
alias key_green is pin_B4                      -- Active LOW.
pin_B4_direction = input                       -- Pin 37 of 40 pin DIP.

-- Aliases for leds.
alias led_amber  is pin_D0                     -- On when connected.
pin_D0_direction = output                      -- Pin 19 of 40 pin DIP.
alias led_red    is pin_D1
pin_D1_direction = output                      -- Pin 20 of 40 pin DIP.
alias led_green is pin_D2
pin_D2_direction = output                      -- Pin 21 of 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate = 9600   -- Default baudrate of module.

-- It is best to use the interrupt based serial routines to prevent data loss
-- when data is received. Adjust the buffer size.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 10 -- size of receive buffer

-- Optional. Wait at most 1 second for a character from the module.
-- const word BLUETOOTH_HC06_READ_TIMEOUT = 10_000 -- 10.000 times 100 us, see library.

-- -------------------------- Includes go here ---------------------------------
include serial_hw_int_cts
include bluetooth_hc06  -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-06. Change to your needs.
const byte DEVICE_PINCODE[] = "1111"                       -- Default is "1234"
const byte DEVICE_NAME[]    = "My HC-06"
const byte DEVICE_BAUDRATE  = BLUETOOTH_HC06_BAUDRATE_9600 -- This is the default.

-- ------------------------- Variable declarations -----------------------------
var byte character
var bit  all_ok

-- -----------------------  Main program starts here ---------------------------

-- Initialize the libraries
serial_hw_init()
bluetooth_hc06_init()

-- LEDs off.
led_amber = LOW
led_red = LOW
led_green = LOW

-- Let's see if the module is available for programming.
all_ok = bluetooth_hc06_available()

-- Check the program pin, if low we will change some default values of the
-- HC-06 module but only if the module is available.
if all_ok & !program_pin then

   -- Change the pincode of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_pin(DEVICE_PINCODE)

   -- Change the name of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_name(DEVICE_NAME)

   -- Change the baudrate. Note that the baudrate changes after a new power up
   -- of the module. Make sure that the PIC also uses this new baudrate after power up.
   all_ok = all_ok &  bluetooth_hc06_set_baudrate(DEVICE_BAUDRATE)

   -- If all went OK, flash the green LED, else flash the red LED.
   if all_ok then
      -- In order to take effect we need to reset the device.
      bluetooth_hc06_reset()
      led_green = HIGH
      _usec_delay(3_000_000)
      led_green = LOW
   else
      led_red = HIGH
      _usec_delay(3_000_000)
      led_red = LOW
   end if

end if

-- We will wait for the device to be connected, that is it will no longer indicate
-- that it is available. Note that if the module is not working it will also
-- not indicate that it is available so this is not 100%. Blink the amber lED
-- while waiting. This step is just for information and can be removed since
-- there is also a LED blinking on the device that shows if the module is
-- connected or not.
while bluetooth_hc06_available() loop
   led_amber = !led_amber
   _usec_delay(500_000)
end loop

-- No longer responding may mean that we are connected.
led_amber = HIGH

-- Main loop.
forever loop

  -- Check if data is received from the Bluetooth Module to control the LEDs.
  if bluetooth_hc06_data_available() then
     character = bluetooth_hc06_data
     if (character == "R") | (character == "r") then
        led_red = !led_red
     elsif (character == "G") | (character == "g") then
        led_green = !led_green
     end if
   end if

   -- Check if we need to send a pressed key.
   if !key_red then
      bluetooth_hc06_data = "R"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if
   if !key_green then
      bluetooth_hc06_data = "G"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if

end loop

Generated by JALlib CHM Help System | Source: bluetooth_hc06.jal


bluetooth_hc06_set_device_name - JALlib Procedures Help

bluetooth_hc06_set_device_name JALLIB FUNCTION

Signature

function bluetooth_hc06_set_device_name(byte in name[]) return bit is

Description

Set the device name. The device name may not be longer than 20 characters.
Returns TRUE when succcesful.

Include

To use this procedure, include the library:

include bluetooth_hc06

Parameters

  • name[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f877a_bluetooth_hc06_slave.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-06 module
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC06 slave module.
--              With this program LEDs can be controlled remotely from a host
--              and when a key is pressed it will be sent to the host. The HC-06
--              can be reprogrammed by making the 'program' pin active low.
--
-- Sources:     Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
--              Guangzhou HC Information Technology Co., Ltd.
--
-- Notes:       The HC-06 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              PIC USART connections to module (40 pin DIP):
--              *) TX: pin 25 of the USART1 of the PIC to the RX pin of the Module.
--              *) RX: pin 26 of the USART1 of the PIC to the TX pin of the Module.
--
include 16f877a

-- ------------------------------- Pragmas -------------------------------------

-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming

-- Enable weak pull-up on port B.
OPTION_REG_NRBPU = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------

-- Programming pin.
alias program_pin is pin_B1                    -- Active LOW.
pin_B1_direction = input                       -- Pin 34 for 40 pin DIP.

-- Aliases for keys.
alias key_red is pin_B2                        -- Active LOW.
pin_B2_direction = input                       -- Pin 35 of 40 pin DIP.
alias key_green is pin_B4                      -- Active LOW.
pin_B4_direction = input                       -- Pin 37 of 40 pin DIP.

-- Aliases for leds.
alias led_amber  is pin_D0                     -- On when connected.
pin_D0_direction = output                      -- Pin 19 of 40 pin DIP.
alias led_red    is pin_D1
pin_D1_direction = output                      -- Pin 20 of 40 pin DIP.
alias led_green is pin_D2
pin_D2_direction = output                      -- Pin 21 of 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate = 9600   -- Default baudrate of module.

-- It is best to use the interrupt based serial routines to prevent data loss
-- when data is received. Adjust the buffer size.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 10 -- size of receive buffer

-- Optional. Wait at most 1 second for a character from the module.
-- const word BLUETOOTH_HC06_READ_TIMEOUT = 10_000 -- 10.000 times 100 us, see library.

-- -------------------------- Includes go here ---------------------------------
include serial_hw_int_cts
include bluetooth_hc06  -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-06. Change to your needs.
const byte DEVICE_PINCODE[] = "1111"                       -- Default is "1234"
const byte DEVICE_NAME[]    = "My HC-06"
const byte DEVICE_BAUDRATE  = BLUETOOTH_HC06_BAUDRATE_9600 -- This is the default.

-- ------------------------- Variable declarations -----------------------------
var byte character
var bit  all_ok

-- -----------------------  Main program starts here ---------------------------

-- Initialize the libraries
serial_hw_init()
bluetooth_hc06_init()

-- LEDs off.
led_amber = LOW
led_red = LOW
led_green = LOW

-- Let's see if the module is available for programming.
all_ok = bluetooth_hc06_available()

-- Check the program pin, if low we will change some default values of the
-- HC-06 module but only if the module is available.
if all_ok & !program_pin then

   -- Change the pincode of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_pin(DEVICE_PINCODE)

   -- Change the name of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_name(DEVICE_NAME)

   -- Change the baudrate. Note that the baudrate changes after a new power up
   -- of the module. Make sure that the PIC also uses this new baudrate after power up.
   all_ok = all_ok &  bluetooth_hc06_set_baudrate(DEVICE_BAUDRATE)

   -- If all went OK, flash the green LED, else flash the red LED.
   if all_ok then
      -- In order to take effect we need to reset the device.
      bluetooth_hc06_reset()
      led_green = HIGH
      _usec_delay(3_000_000)
      led_green = LOW
   else
      led_red = HIGH
      _usec_delay(3_000_000)
      led_red = LOW
   end if

end if

-- We will wait for the device to be connected, that is it will no longer indicate
-- that it is available. Note that if the module is not working it will also
-- not indicate that it is available so this is not 100%. Blink the amber lED
-- while waiting. This step is just for information and can be removed since
-- there is also a LED blinking on the device that shows if the module is
-- connected or not.
while bluetooth_hc06_available() loop
   led_amber = !led_amber
   _usec_delay(500_000)
end loop

-- No longer responding may mean that we are connected.
led_amber = HIGH

-- Main loop.
forever loop

  -- Check if data is received from the Bluetooth Module to control the LEDs.
  if bluetooth_hc06_data_available() then
     character = bluetooth_hc06_data
     if (character == "R") | (character == "r") then
        led_red = !led_red
     elsif (character == "G") | (character == "g") then
        led_green = !led_green
     end if
   end if

   -- Check if we need to send a pressed key.
   if !key_red then
      bluetooth_hc06_data = "R"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if
   if !key_green then
      bluetooth_hc06_data = "G"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if

end loop

Generated by JALlib CHM Help System | Source: bluetooth_hc06.jal


bluetooth_hc06_set_device_pin - JALlib Procedures Help

bluetooth_hc06_set_device_pin JALLIB FUNCTION

Signature

function bluetooth_hc06_set_device_pin(byte in pincode[]) return bit is

Description

Set the device pincode. The pincode must be 4 characters. Returns TRUE when
succesful. The default factory pin is "1234".

Include

To use this procedure, include the library:

include bluetooth_hc06

Parameters

  • pincode[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f877a_bluetooth_hc06_slave.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-06 module
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC06 slave module.
--              With this program LEDs can be controlled remotely from a host
--              and when a key is pressed it will be sent to the host. The HC-06
--              can be reprogrammed by making the 'program' pin active low.
--
-- Sources:     Bluetooth HC-06 Module Datasheet revision 2.2 (2011/04/06)
--              Guangzhou HC Information Technology Co., Ltd.
--
-- Notes:       The HC-06 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              PIC USART connections to module (40 pin DIP):
--              *) TX: pin 25 of the USART1 of the PIC to the RX pin of the Module.
--              *) RX: pin 26 of the USART1 of the PIC to the TX pin of the Module.
--
include 16f877a

-- ------------------------------- Pragmas -------------------------------------

-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming

-- Enable weak pull-up on port B.
OPTION_REG_NRBPU = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------

-- Programming pin.
alias program_pin is pin_B1                    -- Active LOW.
pin_B1_direction = input                       -- Pin 34 for 40 pin DIP.

-- Aliases for keys.
alias key_red is pin_B2                        -- Active LOW.
pin_B2_direction = input                       -- Pin 35 of 40 pin DIP.
alias key_green is pin_B4                      -- Active LOW.
pin_B4_direction = input                       -- Pin 37 of 40 pin DIP.

-- Aliases for leds.
alias led_amber  is pin_D0                     -- On when connected.
pin_D0_direction = output                      -- Pin 19 of 40 pin DIP.
alias led_red    is pin_D1
pin_D1_direction = output                      -- Pin 20 of 40 pin DIP.
alias led_green is pin_D2
pin_D2_direction = output                      -- Pin 21 of 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate = 9600   -- Default baudrate of module.

-- It is best to use the interrupt based serial routines to prevent data loss
-- when data is received. Adjust the buffer size.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 10 -- size of receive buffer

-- Optional. Wait at most 1 second for a character from the module.
-- const word BLUETOOTH_HC06_READ_TIMEOUT = 10_000 -- 10.000 times 100 us, see library.

-- -------------------------- Includes go here ---------------------------------
include serial_hw_int_cts
include bluetooth_hc06  -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-06. Change to your needs.
const byte DEVICE_PINCODE[] = "1111"                       -- Default is "1234"
const byte DEVICE_NAME[]    = "My HC-06"
const byte DEVICE_BAUDRATE  = BLUETOOTH_HC06_BAUDRATE_9600 -- This is the default.

-- ------------------------- Variable declarations -----------------------------
var byte character
var bit  all_ok

-- -----------------------  Main program starts here ---------------------------

-- Initialize the libraries
serial_hw_init()
bluetooth_hc06_init()

-- LEDs off.
led_amber = LOW
led_red = LOW
led_green = LOW

-- Let's see if the module is available for programming.
all_ok = bluetooth_hc06_available()

-- Check the program pin, if low we will change some default values of the
-- HC-06 module but only if the module is available.
if all_ok & !program_pin then

   -- Change the pincode of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_pin(DEVICE_PINCODE)

   -- Change the name of the module.
   all_ok = all_ok & bluetooth_hc06_set_device_name(DEVICE_NAME)

   -- Change the baudrate. Note that the baudrate changes after a new power up
   -- of the module. Make sure that the PIC also uses this new baudrate after power up.
   all_ok = all_ok &  bluetooth_hc06_set_baudrate(DEVICE_BAUDRATE)

   -- If all went OK, flash the green LED, else flash the red LED.
   if all_ok then
      -- In order to take effect we need to reset the device.
      bluetooth_hc06_reset()
      led_green = HIGH
      _usec_delay(3_000_000)
      led_green = LOW
   else
      led_red = HIGH
      _usec_delay(3_000_000)
      led_red = LOW
   end if

end if

-- We will wait for the device to be connected, that is it will no longer indicate
-- that it is available. Note that if the module is not working it will also
-- not indicate that it is available so this is not 100%. Blink the amber lED
-- while waiting. This step is just for information and can be removed since
-- there is also a LED blinking on the device that shows if the module is
-- connected or not.
while bluetooth_hc06_available() loop
   led_amber = !led_amber
   _usec_delay(500_000)
end loop

-- No longer responding may mean that we are connected.
led_amber = HIGH

-- Main loop.
forever loop

  -- Check if data is received from the Bluetooth Module to control the LEDs.
  if bluetooth_hc06_data_available() then
     character = bluetooth_hc06_data
     if (character == "R") | (character == "r") then
        led_red = !led_red
     elsif (character == "G") | (character == "g") then
        led_green = !led_green
     end if
   end if

   -- Check if we need to send a pressed key.
   if !key_red then
      bluetooth_hc06_data = "R"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if
   if !key_green then
      bluetooth_hc06_data = "G"
     _usec_delay(50_000) -- Key debounce & repeat.
   end if

end loop

Generated by JALlib CHM Help System | Source: bluetooth_hc06.jal


bmi160_init - JALlib Procedures Help

bmi160_init JALLIB PROCEDURE

Signature

procedure bmi160_init() is

Description

Initialize BMI160

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

None

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_accelerometer_x - JALlib Procedures Help

bmi_160_accelerometer_x JALLIB FUNCTION

Signature

function bmi_160_accelerometer_x() return word is

Description

Read accelerometer X axis

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_accelerometer_y - JALlib Procedures Help

bmi_160_accelerometer_y JALLIB FUNCTION

Signature

function bmi_160_accelerometer_y() return word is

Description

Read accelerometer Y axis

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_accelerometer_z - JALlib Procedures Help

bmi_160_accelerometer_z JALLIB FUNCTION

Signature

function bmi_160_accelerometer_z() return word is

Description

Read accelerometer Z axis

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_communication_test - JALlib Procedures Help

bmi_160_communication_test JALLIB FUNCTION

Signature

function bmi_160_communication_test() return bit is

Description

communication test

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_gyro_x - JALlib Procedures Help

bmi_160_gyro_x JALLIB FUNCTION

Signature

function bmi_160_gyro_x() return word is

Description

Read gyro Z axis

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_gyro_y - JALlib Procedures Help

bmi_160_gyro_y JALLIB FUNCTION

Signature

function bmi_160_gyro_y() return word is

Description

Read gyro Z axis

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmi_160_gyro_z - JALlib Procedures Help

bmi_160_gyro_z JALLIB FUNCTION

Signature

function bmi_160_gyro_z() return word is

Description

Read gyro Z axis

Include

To use this procedure, include the library:

include accelerometer_gyroscope_bmi160

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_accelerometer_gyroscope_bmi160.jal

-- Title: Accelerometer & Gyroscope BMI160
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads x,y,z values from BMI160's
--              accelerometer & gyroscope and sends it via serial port.
--
-- Sources:
-- http://www.mouser.com/ds/2/783/BST-BMI160-DS000-07-786474.pdf
--
-- This file has been manually generated.
--
include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a1
alias led_direction is pin_a1_direction
led_direction = output

-- setup BMI160 accelerometer via SPI
alias mbi160_chip_select is pin_ss
alias mbi160_chip_select_direction is pin_ss_direction
--
include accelerometer_gyroscope_bmi160
bmi160_init()
--
if bmi_160_communication_test() then
   print_string(serial_data,"BMI160 Loaded OK")
else
   print_string(serial_data,"BMI160 communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   print_string(serial_data,"Acc X: ")
   format_word_dec(serial_data,bmi_160_accelerometer_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_accelerometer_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_accelerometer_z(),5,0)

   print_string(serial_data,"         Gyro X: ")
   format_word_dec(serial_data,bmi_160_gyro_x(),5,0)
   print_string(serial_data,"   Y: ")
   format_word_dec(serial_data,bmi_160_gyro_y(),5,0)
   print_string(serial_data,"   Z: ")
   format_word_dec(serial_data,bmi_160_gyro_z(),5,0)
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: accelerometer_gyroscope_bmi160.jal


bmp085.jal - JALLIB Library Documentation

bmp085.jal JALLIB LIBRARY

Title

bmp085 digital pressure sensor I2C routines.

Author

Urmas Joeleht, Copyright (c) 2014...2015, all rights reserved., Adapted-by:

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

BMP085 digital pressure sensor I2C routines.
Functions and procedures:
get_2_bytes() - for internal use. Address as input, returns 2 bytes of data
bmp085_init() - reads calibration data from chip
get_uncompensated_temperature() - gets raw temp from chip
get_uncompensated_pressure() - gets raw pressure from chip
calculate_true_temperature() - calculates true temerature, using factory calibration data
calculate_true_pressure() - calculates true pressure, using factory calibration data
For end user:
bmp085_return_temperature_and_pressure(). Input - "mode". Returns temperature (sword), pressure(dword) and success (bit)

Notes

3,3V device

Sources

http://www.bosch-sensortec.com/content/language1/downloads/BST-BMP085-DS000-05.pdf
--------------------------------
From datasheet:
--------------------------------
Chip I2C address

Constants and Variables

BMP085_I2C_WR_ADDR - const byte = 0xEE --write address
write address
BMP085_I2C_RD_ADDR - const byte = 0xEF --read address
read address
BMP085_AC1_ADDR - const byte = 0xAA
BMP085_AC2_ADDR - const byte = 0xAC
BMP085_AC3_ADDR - const byte = 0xAE
BMP085_AC4_ADDR - const byte = 0xB0
BMP085_AC5_ADDR - const byte = 0xB2
BMP085_AC6_ADDR - const byte = 0xB4
BMP085_B1_ADDR - const byte = 0xB6
BMP085_B2_ADDR - const byte = 0xB8
BMP085_MB_ADDR - const byte = 0xBA
BMP085_MC_ADDR - const byte = 0xBC
BMP085_MD_ADDR - const byte = 0xBE
BMP085_CONTROL_REG - const byte = 0xF4
BMP085_TEMP_PRESS_MSB - const byte = 0xF6
BMP085_READ_TEMP_CMD - const byte = 0x2E
BMP085_READ_PRESSURE_CMD - const byte = 0x34
bmp085_b5 - var sdword
bmp085_mode - var byte
bmp085_true_temp - var sword
bmp085_true_pressure - var dword
result - var word
conversation_time - var byte
bmp085_temp_counter - var byte = 127

Routines

  • bmp085_init - Procedure
  • bmp085_return_temperature_and_pressure - Procedure
  • bmp085_return_temperature_and_pressure_fast - Procedure
  • calculate_true_pressure - Function returns dword
  • calculate_true_temperature - Function returns sword
  • get_uncompensated_temp - Function returns word


bmp085_init - JALlib Procedures Help

bmp085_init JALLIB PROCEDURE

Signature

procedure bmp085_init(bit out ack) is

Description

Get factory calibration data from chip and put it in variables

Include

To use this procedure, include the library:

include bmp085

Parameters

  • ack - bit out

Return Value

None

Example

From sample file: 16f1519_bmp085.jal

-- Title: Sample file of using Bosch pressure sensor
-- Author: Urmas Joeleht, Copyright (c) 2014..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample program for use of BMP085 ressure sensor with Microchip PIC16lf1516.
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 29. Oct 2014 17:49:36.
--
-- ------------------------------------------------------
--
include 16f1519

pragma target clock 16_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
OSCCON_IRCF = 0b1111                -- 16_000_000 Hz
pragma target WDT      disabled     -- no watchdog
pragma target LVP      enabled      -- allow Low Voltage Programming
pragma target MCLR     external     -- reset externally
--
enable_digital_io()
alias   led      is pin_c1
pin_c1_direction =  output

include delay
include print
------------------------------
--SERIAL HW
------------------------------
const serial_hw_baudrate = 115_200
var bit serial_ctsinv
const serial_overflow_discard = false
const   SERIAL_XMTBUFSIZE  = 255
const   SERIAL_RCVBUFSIZE  = 1
const   SERIAL_DELTA       = 1
include serial_hardware

serial_hw_init()
------------------------------
--I2C software
------------------------------
alias i2c_scl is pin_d1
alias i2c_scl_direction is pin_d1_direction
alias i2c_sda is pin_d0
alias i2c_sda_direction is pin_d0_direction
var byte _i2c_bus_speed = 1
const bit _i2c_level = true   ; i2c levels (not SMB)
include i2c_software
i2c_initialize()
var byte i2c_tx_buffer[2]
var byte i2c_rx_buffer[2]
include i2c_level1
------------------------------
--BMP085
------------------------------
-- comment out next 3 lines if not using eoc pin (End Of Conversation)
-- If not using EOC  pin, program waits max conversation time, to be sure
-- conversation is ended
alias pin_eoc is pin_d4                       --Optional
alias pin_eoc_direction is pin_d4_direction   --Optional
pin_eoc_direction = input                     --Optional

include bmp085
var bit ok
bmp085_init(ok)
------------------------------
--variables for sample
------------------------------
var byte mode_string[] = "Mode: "
var byte temp_string[] = "Temperature: "
var byte press_string[] = "Pressure: "
var byte correct_string[] = "Data "
var byte ok_string[] = "Ok"
var byte nok_string[] = "Not Ok"
var sword tmp
var dword prs
var bit success
var byte mode -- for testing purposes
-----------------------------
-- Forever loop
-- After 1 second program asks temperature and pressure from chip with different mode setting.
-----------------------------
forever loop
   if mode >= 3 then
      mode = 0
   else
      mode = mode + 1
   end if
   bmp085_return_temperature_and_pressure_fast (mode, tmp, prs, success)
   print_string(serial_hw_data,mode_string)
   print_byte_dec(serial_hw_data,mode)
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,temp_string)
   print_sword_dec(serial_hw_data,tmp)
   serial_hw_data = "C"
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,press_string)
   print_dword_dec(serial_hw_data,prs)
   serial_hw_data = "P"
   serial_hw_data = "a"
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,correct_string)
   if success == 1 then
      print_string(serial_hw_data,ok_string)
   else
      print_string(serial_hw_data,nok_string)
   end if
   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)
   led = !led
   delay_1s(1)
end loop

Generated by JALlib CHM Help System | Source: bmp085.jal


bmp180.jal - JALLIB Library Documentation

bmp180.jal JALLIB LIBRARY

Title

Library functions for the BMP180 pressure sensor.

Author

Rob Jansen, Copyright (c) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library functions for the BMP180 pressure sensor. The main
program has to setup the IIC communication using an IIC clock of
at most 3.4 MHz.

Sources

Bosch BMP180 Datasheet version 2.5, document BST-BMP180-DS000-09.

============================= Public API=====================================

---------------------------- Public constants -------------------------------

Resolution modes and oversampling settings.

Constants and Variables

BMP180_MODE_ULTRA_LOW_POWER - const byte = 0 -- Default.
Default.
BMP180_MODE_STANDARD - const byte = 1
BMP180_MODE_HIGH_RES - const byte = 2
BMP180_MODE_ULTRA_HIGH_RES - const byte = 3

Routines

  • _bmp180_calculate_b5 - Function returns sdword
  • _bmp180_read_data_byte - Function returns byte
  • _bmp180_read_data_word - Function returns word
  • _bmp180_write_data_byte - Procedure
  • _read_raw_pressure - Function returns dword
  • _read_raw_temperature - Function returns dword
  • bmp180_get_mode - Function returns byte
  • bmp180_get_pressure - Function returns sdword
  • bmp180_get_temperature - Function returns sword
  • bmp180_init - Procedure
  • bmp180_reset - Procedure
  • bmp180_set_mode - Procedure


bmp180_get_pressure - JALlib Procedures Help

bmp180_get_pressure JALLIB FUNCTION

Signature

function bmp180_get_pressure() return sdword is

Description

Get the current pressure. This is a blocking call. The delay is depending on
the last selected resolution mode and can be larger than 31 ms. See datasheet.
Pressure is returned in Pascal (Pa).

Include

To use this procedure, include the library:

include bmp180

Parameters

None

Return Value

None

Example

From sample file: 16f1825_bmp180.jal

-- Title: Sample program for the BMP180 pressure sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the BMP180 pressure sensor, controlled via IIC.
--              The program prints the temperature and pressure via the serial port
--              using different resoluton modes for the pressure measurement.
--
-- Sources: Bosch BMP180 Datasheet version 2.5, document BST-BMP180-DS000-09.
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- Now include the library and initialize.
include bmp180
bmp180_init()

-- Variables.
var sdword pressure
var sword temperature

print_string(serial, "BMP180 temperature and pressure sensor sample program.\r\n")

forever  loop

   -- Read the temperature.
   temperature =  bmp180_get_temperature()
   print_string(serial, "The current temperature in 0.1 degrees Celcius is: ")
   print_sdword_dec(serial, temperature)
   print_crlf(serial)
   -- Print in format xx.x.
   print_string(serial, "The current temperature in degrees Celcius is: ")
   if (temperature < 0) then
      serial = "-"
   else
      serial = "+"
   end if
   print_word_dec(serial, word(temperature) / 10)
   serial = "."
   print_word_dec(serial, word(temperature) % 10)
   print_crlf(serial)

   -- The pressure can be calulated with different resolution by changing the mode.
   -- The initial mode after reset (and init) is BMP180_MODE_ULTRA_LOW_POWER.
   if (bmp180_get_mode == BMP180_MODE_ULTRA_LOW_POWER) then
      print_string(serial, "Pressure in standard mode.\r\n")
      bmp180_set_mode(BMP180_MODE_STANDARD)
   elsif (bmp180_get_mode == BMP180_MODE_STANDARD) then
      print_string(serial, "Pressure in high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_HIGH_RES)
   elsif (bmp180_get_mode == BMP180_MODE_HIGH_RES) then
      print_string(serial, "Pressure in ultra high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_HIGH_RES)
   else
      print_string(serial, "Pressure in ultra low power mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_LOW_POWER)
   end if

   -- Read the pressure, this can take some time depending on the resolution mode.
   pressure = bmp180_get_pressure()
   print_string(serial, "The current pressure in Pa is: ")
   print_sdword_dec(serial, pressure)
   print_crlf(serial)
   print_string(serial, "The current pressure in hPa is: ")
   print_sdword_dec(serial, pressure / 100)
   serial = "."
   print_sdword_dec(serial, pressure % 100)
   print_crlf(serial)
   print_crlf(serial)

   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: bmp180.jal


bmp180_get_temperature - JALlib Procedures Help

bmp180_get_temperature JALLIB FUNCTION

Signature

function bmp180_get_temperature() return sword is

Description

Get the current temperature. This is a blocking call. The delay is depending
on the last selected resolution mode and is at least 4.5 ms. See datasheet.
Temperature is returned as a value of 0.1 degrees Celcius.

Include

To use this procedure, include the library:

include bmp180

Parameters

None

Return Value

None

Example

From sample file: 16f1825_bmp180.jal

-- Title: Sample program for the BMP180 pressure sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the BMP180 pressure sensor, controlled via IIC.
--              The program prints the temperature and pressure via the serial port
--              using different resoluton modes for the pressure measurement.
--
-- Sources: Bosch BMP180 Datasheet version 2.5, document BST-BMP180-DS000-09.
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- Now include the library and initialize.
include bmp180
bmp180_init()

-- Variables.
var sdword pressure
var sword temperature

print_string(serial, "BMP180 temperature and pressure sensor sample program.\r\n")

forever  loop

   -- Read the temperature.
   temperature =  bmp180_get_temperature()
   print_string(serial, "The current temperature in 0.1 degrees Celcius is: ")
   print_sdword_dec(serial, temperature)
   print_crlf(serial)
   -- Print in format xx.x.
   print_string(serial, "The current temperature in degrees Celcius is: ")
   if (temperature < 0) then
      serial = "-"
   else
      serial = "+"
   end if
   print_word_dec(serial, word(temperature) / 10)
   serial = "."
   print_word_dec(serial, word(temperature) % 10)
   print_crlf(serial)

   -- The pressure can be calulated with different resolution by changing the mode.
   -- The initial mode after reset (and init) is BMP180_MODE_ULTRA_LOW_POWER.
   if (bmp180_get_mode == BMP180_MODE_ULTRA_LOW_POWER) then
      print_string(serial, "Pressure in standard mode.\r\n")
      bmp180_set_mode(BMP180_MODE_STANDARD)
   elsif (bmp180_get_mode == BMP180_MODE_STANDARD) then
      print_string(serial, "Pressure in high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_HIGH_RES)
   elsif (bmp180_get_mode == BMP180_MODE_HIGH_RES) then
      print_string(serial, "Pressure in ultra high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_HIGH_RES)
   else
      print_string(serial, "Pressure in ultra low power mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_LOW_POWER)
   end if

   -- Read the pressure, this can take some time depending on the resolution mode.
   pressure = bmp180_get_pressure()
   print_string(serial, "The current pressure in Pa is: ")
   print_sdword_dec(serial, pressure)
   print_crlf(serial)
   print_string(serial, "The current pressure in hPa is: ")
   print_sdword_dec(serial, pressure / 100)
   serial = "."
   print_sdword_dec(serial, pressure % 100)
   print_crlf(serial)
   print_crlf(serial)

   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: bmp180.jal


bmp180_init - JALlib Procedures Help

bmp180_init JALLIB PROCEDURE

Signature

procedure bmp180_init() is

Description

Initialize the BMP180 library. The resoluton mode is set to
BMP180_MODE_ULTRA_LOW_POWER. The IIC interface must be initialized.

Include

To use this procedure, include the library:

include bmp180

Parameters

None

Return Value

None

Example

From sample file: 16f1825_bmp180.jal

-- Title: Sample program for the BMP180 pressure sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the BMP180 pressure sensor, controlled via IIC.
--              The program prints the temperature and pressure via the serial port
--              using different resoluton modes for the pressure measurement.
--
-- Sources: Bosch BMP180 Datasheet version 2.5, document BST-BMP180-DS000-09.
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- Now include the library and initialize.
include bmp180
bmp180_init()

-- Variables.
var sdword pressure
var sword temperature

print_string(serial, "BMP180 temperature and pressure sensor sample program.\r\n")

forever  loop

   -- Read the temperature.
   temperature =  bmp180_get_temperature()
   print_string(serial, "The current temperature in 0.1 degrees Celcius is: ")
   print_sdword_dec(serial, temperature)
   print_crlf(serial)
   -- Print in format xx.x.
   print_string(serial, "The current temperature in degrees Celcius is: ")
   if (temperature < 0) then
      serial = "-"
   else
      serial = "+"
   end if
   print_word_dec(serial, word(temperature) / 10)
   serial = "."
   print_word_dec(serial, word(temperature) % 10)
   print_crlf(serial)

   -- The pressure can be calulated with different resolution by changing the mode.
   -- The initial mode after reset (and init) is BMP180_MODE_ULTRA_LOW_POWER.
   if (bmp180_get_mode == BMP180_MODE_ULTRA_LOW_POWER) then
      print_string(serial, "Pressure in standard mode.\r\n")
      bmp180_set_mode(BMP180_MODE_STANDARD)
   elsif (bmp180_get_mode == BMP180_MODE_STANDARD) then
      print_string(serial, "Pressure in high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_HIGH_RES)
   elsif (bmp180_get_mode == BMP180_MODE_HIGH_RES) then
      print_string(serial, "Pressure in ultra high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_HIGH_RES)
   else
      print_string(serial, "Pressure in ultra low power mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_LOW_POWER)
   end if

   -- Read the pressure, this can take some time depending on the resolution mode.
   pressure = bmp180_get_pressure()
   print_string(serial, "The current pressure in Pa is: ")
   print_sdword_dec(serial, pressure)
   print_crlf(serial)
   print_string(serial, "The current pressure in hPa is: ")
   print_sdword_dec(serial, pressure / 100)
   serial = "."
   print_sdword_dec(serial, pressure % 100)
   print_crlf(serial)
   print_crlf(serial)

   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: bmp180.jal


bmp180_set_mode - JALlib Procedures Help

bmp180_set_mode JALLIB PROCEDURE

Signature

procedure bmp180_set_mode(byte in mode) is

Description

Set the resolution mode.

Include

To use this procedure, include the library:

include bmp180

Parameters

  • mode - byte in

Return Value

None

Example

From sample file: 16f1825_bmp180.jal

-- Title: Sample program for the BMP180 pressure sensor.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for the BMP180 pressure sensor, controlled via IIC.
--              The program prints the temperature and pressure via the serial port
--              using different resoluton modes for the pressure measurement.
--
-- Sources: Bosch BMP180 Datasheet version 2.5, document BST-BMP180-DS000-09.
--

include 16f1825

-- This program uses the internal oscillator at 16 MHz (just to be sure on 3.3 Volt).
pragma target clock    16_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1111                 -- Set 16 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)     -- Let the hardware stabilize.

-- Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Definitions for the IIC interface.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)

-- When using i2c_hardware.
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware

-- When using i2c_software.
-- alias i2c_scl_direction is pin_C0_direction
-- alias i2c_sda_direction is pin_C1_direction
-- const _i2c_scl_timeout = 1_000  -- units are in bit-times.
-- include i2c_software

-- Now initialize the IIC library.
i2c_initialize()

-- Now include the library and initialize.
include bmp180
bmp180_init()

-- Variables.
var sdword pressure
var sword temperature

print_string(serial, "BMP180 temperature and pressure sensor sample program.\r\n")

forever  loop

   -- Read the temperature.
   temperature =  bmp180_get_temperature()
   print_string(serial, "The current temperature in 0.1 degrees Celcius is: ")
   print_sdword_dec(serial, temperature)
   print_crlf(serial)
   -- Print in format xx.x.
   print_string(serial, "The current temperature in degrees Celcius is: ")
   if (temperature < 0) then
      serial = "-"
   else
      serial = "+"
   end if
   print_word_dec(serial, word(temperature) / 10)
   serial = "."
   print_word_dec(serial, word(temperature) % 10)
   print_crlf(serial)

   -- The pressure can be calulated with different resolution by changing the mode.
   -- The initial mode after reset (and init) is BMP180_MODE_ULTRA_LOW_POWER.
   if (bmp180_get_mode == BMP180_MODE_ULTRA_LOW_POWER) then
      print_string(serial, "Pressure in standard mode.\r\n")
      bmp180_set_mode(BMP180_MODE_STANDARD)
   elsif (bmp180_get_mode == BMP180_MODE_STANDARD) then
      print_string(serial, "Pressure in high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_HIGH_RES)
   elsif (bmp180_get_mode == BMP180_MODE_HIGH_RES) then
      print_string(serial, "Pressure in ultra high resolution mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_HIGH_RES)
   else
      print_string(serial, "Pressure in ultra low power mode.\r\n")
      bmp180_set_mode(BMP180_MODE_ULTRA_LOW_POWER)
   end if

   -- Read the pressure, this can take some time depending on the resolution mode.
   pressure = bmp180_get_pressure()
   print_string(serial, "The current pressure in Pa is: ")
   print_sdword_dec(serial, pressure)
   print_crlf(serial)
   print_string(serial, "The current pressure in hPa is: ")
   print_sdword_dec(serial, pressure / 100)
   serial = "."
   print_sdword_dec(serial, pressure % 100)
   print_crlf(serial)
   print_crlf(serial)

   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: bmp180.jal


Built-in Functions - JAL Language Syntax Reference

Built-in Functions JALV2 SYNTAX

Description

JALv2 attempts to be a minimal language with most complex operations done with sub-programs, however some functions simply cannot be efficiently supported externally.

Generated by JAL Syntax Documentation System | Source: DITA


calendar - JALlib Procedures Help

calendar JALLIB PROCEDURE

Signature

procedure calendar() is -- should be called at least once a minute

Description

Title: Calendar, takes care of ranges for seconds, minutes, date, month, year
Author: Eur van Andel, Copyright (c) 2008, all rights reserved.
Adapted-by:
Compiler: >=2.4h
This file is part of jallib (https://github.com/jallib/jallib)
Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
Description: This library has only one fuction: calendar(). It assumes the following variables:
var volatile byte seconds (typically updated by an ISR)
var byte hours, minutes, date, month
var word year
It knows the leap years until 2099.

Include

To use this procedure, include the library:

include calendar

Parameters

None

Return Value

None

Example

From sample file: 16f876a_rtc_timeset.jal

-- Title: Sample program to show usage of rtc_isr, with a time set procedure
-- Author: Eur van Andel, Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber, Rob Hamerling
-- Compiler: 2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:  http://www.romanblack.com/one_sec.htm, http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
--
-- Description: This program shows how to handle Real Time in a PIC,
-- complete with setting the initial time by the compiler OS
-- via the timeset.py script, which writes the now.jal file
-- The user can set the time via the timeset() procedure,
-- which uses the keyboard and LCD. This layout is tailored to a 20x4 LCD.
--
-- This file has been generated by hand (manually maintained)
--

-- ------------------- SELECT PIC ----------------------------
include 16f876a

pragma target clock     20_000_000           -- 20 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

T0CON_T0CS = 0                               -- internal instruction cycle clock
T0CON_PSA = 1                                -- prescaler assigned to Timer0 module
T0CON_T0PS = 0                               -- no prescaling

-- ------------------------ LIBRARIES ------------------------

include rtc_isr_tmr0

var byte minutes                 -- seconds in ISR lib
var byte hours

var byte date
var byte month
var word year

include now                      -- sets the time to system time + one minute
                                 -- = compile and burn time
                                 -- should be generated just before compiling

include calendar                 -- 60/24/27..31/12 range limits
pragma eedata 250                -- to check if first boot after programming

include delay                    -- used by LCD lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS                 is pin_b5       -- LCD command/data select.
alias LCD_EN                 is pin_b4       -- LCD data trigger
alias LCD_dataport           is portb_low    -- LCD data nibble
portb_direction              = all_output    -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting
include pic_data_eeprom                      -- to save time when no power

var byte dummy
alias keyscan  is portc_low                  -- rows of keyboard
portc_low_direction = all_input
alias keydrive is portb_low                  -- columns of keyboard, also LCD data
var byte keydrive_direction = dummy
include keyboard                             -- read for schematics

-- ------------------------ PROCEDURES ------------------------

procedure time_set() is
lcd_clear_screen()
while getkey() != 0x0C loop        -- wait until C, bottom right key

   lcd_cursor_position(0,0)
   const byte str4[] = "timeset menu C=exit"
   print_string(lcd, str4)

   lcd_cursor_position(1,0)
   format_time_hms(lcd, hours, minutes, seconds)
   lcd = " "
   print_byte_dec(lcd, date)
   lcd = "-"
   print_byte_dec(lcd, month)
   lcd = "-"
   print_word_dec(lcd, year)
   lcd = " "

   const byte str5[] = " 1  2 use 3  F   7"
   const byte str6[] = " 4  5 key 6  E   A"
   lcd_cursor_position(2,0)                           -- line 3
   print_string(lcd, str5)
   lcd_cursor_position(3,0)                           -- line 4
   print_string(lcd, str6)

   if getkey() == 1 then
      hours = hours + 1
         if hours > 23 then
               hours = hours - 24
         end if
   end if
   if getkey() == 4 then  hours = hours - 1
      if hours > 127 then     -- through zero
         hours = hours + 24      -- 255 + 24 = 23
      end if
   end if
   if getkey() == 2 then  minutes = minutes + 1
      if minutes > 59 then
         minutes = minutes - 60
      end if
   end if
   if getkey() == 5 then  minutes = minutes - 1
      if minutes > 127 then      -- through zero
         minutes = minutes + 60  -- 255 + 60 = 59
      end if
   end if
   if getkey() == 3 then  date = date + 1
      if date > 31 then
         date = date - 31
      end if
   end if
   if getkey() == 6 then  date = date - 1
      if date > 127 then      -- through zero
         date = date + 32     -- 255 + 32 = 31
      end if
   end if
   if getkey() == 0x0F then  month = month + 1
      if month > 12 then
         month = month - 12
      end if
   end if
   if getkey() == 0x0E then  month = month - 1
      if month > 127 then
         month = month + 13      -- 255 +13 = 12
      end if
   end if
   if getkey() == 7 then
      year = year + 1
   end if
   if getkey() == 0x0A then
      year = year - 1
   end if

   calendar

   delay_100ms(2)

end loop       -- getkey() = # or 0x0F
-- time is set here, ISR can be off
data_eeprom_write(0, minutes)
data_eeprom_write(1, hours)
data_eeprom_write(2, date)
data_eeprom_write(3, month)
data_eeprom_write_word(4, year)

lcd_clear_screen()
end procedure        -- ----------------- TIME SET  ----------------------

-- -------------------------- START PROGRAM -----------------

if data_eeprom(0) != 250 then       -- not first boot after programming
   seconds = 0                      -- time isn't accurate anyway
   data_eeprom_read(0, minutes)     -- get old time from eeprom
   data_eeprom_read(1, hours)
   data_eeprom_read(2, date)
   data_eeprom_read(3, month)
   data_eeprom_read_word(4, year)
else
   data_eeprom_write(0, minutes)    -- save present time to eeprom
   data_eeprom_write(1, hours)      -- present time comes from now.jal
   data_eeprom_write(2, date)
   data_eeprom_write(3, month)
   data_eeprom_write_word(4, year)
end if

INTCON_TMR0IE = on                  -- if your PIC freezes, comment these lines
INTCON_GIE = on                     -- to see if the ISR is messed up

lcd_clear_screen()
forever  loop
   lcd_cursor_position(0,0)
   const byte str1[] = "Time RTC sample"
   print_string(lcd, str1)

   lcd_cursor_position(1,0)
   print_byte_dec(lcd, date)
   lcd = "-"
   print_byte_dec(lcd, month)
   lcd = "-"
   print_word_dec(lcd, year)
   lcd = " "
   if seconds > 59 then
      calendar()
   end if
   format_time_hms(lcd, hours, minutes, seconds)

   lcd_cursor_position(3,0)             -- fourth line
   const byte str3[] = "press 9 to set time"
   print_string(lcd, str3)
   if getkey() == 9 then
      time_set()
   end if

   delay_100ms(2)                      -- for LCD viewing

end loop

Generated by JALlib CHM Help System | Source: calendar.jal


calendar.jal - JALLIB Library Documentation

calendar.jal JALLIB LIBRARY

Title

Calendar, takes care of ranges for seconds, minutes, date, month, year

Author

Eur van Andel, Copyright (c) 2008, all rights reserved., Adapted-by:

Compiler

>=2.4h

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library has only one fuction: calendar(). It assumes the following variables:
var volatile byte seconds (typically updated by an ISR)
var byte hours, minutes, date, month
var word year
It knows the leap years until 2099.

Routines

  • calendar - Procedure


can_adapter.jal - JALLIB Library Documentation

can_adapter.jal JALLIB LIBRARY

Title

CAN to UART adapter library

Author

William Welch Copyright (c) 2010, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

bridge/gateway between RS232 and CAN bus. Uses ASCII encapsulation,
compatible with the Socket-CAN SLCAN API, and adapters such as
LAWICEL and VScom USB-CAN.

Sources

Socket-CAN, in particular the SLCAN API. http://developer.berlios.de/projects/socketcan/
also, the LAWICEL CAN-USB and Easylink adapter manuals.
Compatibility testing has been done using the CANHACKER tool.
See http://www.canhack.de/

Constants and Variables

can_adapter_is_open - var bit = 0

Routines

  • _can_pdec8 - Procedure
  • can_check_can_rx - Function returns bit
  • can_check_uart_rx - Procedure
  • can_closed_cmd - Function returns bit
  • can_modeless_cmd - Function returns bit
  • can_open_cmd - Function returns bit


can_ascii.jal - JALLIB Library Documentation

can_ascii.jal JALLIB LIBRARY

Title

ASCII encapsulation of CAN messages

Author

William Welch Copyright (c) 2009, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

ASCII-to-CAN and CAN-to-ASCII routines. The intent is to be compatible with
the SLCAN API. These routines may be used, for example, to implement a RS232 to CAN adapter

Sources

Socket-CAN, in particular the SLCAN API. http://developer.berlios.de/projects/socketcan/
also, the LAWICEL CAN-USB adapter.
Excerpt cut/pasted from SLCAN.C:
A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
frame format) a data length code (can_dlc) which can be from 0 to 8
and up to <can_dlc> data bytes as payload.
Additionally a CAN frame may become a remote transmission frame if the
RTR-bit is set. This causes another ECU to send a CAN frame with the
given can_id.
The SLCAN ASCII representation of these different frame types is:
<type> <id> <dlc> <data>*
Extended frames (29 bit) are defined by capital characters in the type.
RTR frames are defined as 'r' types - normal frames have 't' type:
t => 11 bit data frame
r => 11 bit RTR frame
T => 29 bit data frame
R => 29 bit RTR frame
The <id> is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64).
The <dlc> is a one byte ASCII number ('0' - '8')
The <data> section has at much ASCII Hex bytes as defined by the <dlc>
Examples:
t1230 : can_id 0x123, can_dlc 0, no data
t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33
T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55
r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request

Routines

  • _ascii2bin - Function returns byte
  • ascii_to_can - Function returns bit
  • can_to_ascii - Function returns byte


can_bicolor_leds.jal - JALLIB Library Documentation

can_bicolor_leds.jal JALLIB LIBRARY

Title

CANbus bicolor LED library

Author

William Welch and Eur van Andel Copyright (c) 2010, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

implements LED blinks compatible with CANopen spec.

Sources

Cia Draft Recommendation 303, Part 3, Indicator specification
This library leverages a timer 'interval' library, such as timer0_isr_interval or
timer0_poll_interval. Either one may be used. The isr version will be provide the most
precise timing, but the polled version should be adequate also. This library requires
two interval 'slots', but you may use additional interval slots for your own application.
Since this library does not require an ISR, it depends on occasional 'polling' from your
application. If you need to make a lengthy 'delay' in your application, please use the
100mS delay routine provided by this library whenever possible.
This library requires the following constants:
CANLED_BLINK_INTERVAL_SLOT used in the call to 'set_delay' and 'check_delay' for LED blinking.
CANLED_DELAY_INTERVAL_SLOT used to implement the 100mS delay described above.
CANLED_INTERVAL_100MS the number of 'interval ticks' equal to 100mS
And the LED I/O pin:
alias can_led is pin_b1
alias can_led_dir is pin_b1_direction

Constants and Variables

can_led_state - var byte = 0
can_led_red_func - var byte = CANLED_OFF
can_led_green_func - var byte = CANLED_OFF
can_led_red_opcode - var byte = CANLED_OFF
can_led_green_opcode - var byte = CANLED_OFF

Routines

  • can_green_1flash - Procedure
  • can_green_2flash - Procedure
  • can_green_3flash - Procedure
  • can_green_blink - Procedure
  • can_green_off - Procedure
  • can_green_on - Procedure
  • can_led_delay100ms - Procedure
  • can_led_poll - Procedure
  • can_red_1flash - Procedure
  • can_red_2flash - Procedure
  • can_red_3flash - Procedure
  • can_red_4flash - Procedure
  • can_red_blink - Procedure
  • can_red_off - Procedure
  • can_red_on - Procedure
  • can_set_leds - Procedure


can_check_can_rx - JALlib Procedures Help

can_check_can_rx JALLIB FUNCTION

Signature

function can_check_can_rx(volatile byte out device, dword in out can_id, byte in out can_data[8], byte in out data_len) return bit is

Description

this routine encapsulates incoming CANbus messages, and sends the resulting ASCII out to the UART.
a copy of the CANbus message is also returned to the caller.
device: uart device, e.g. serial_hw_data

Include

To use this procedure, include the library:

include can_adapter

Parameters

  • device - byte out
  • can_id - dword in out
  • can_data[] - byte in out
  • data_len - byte in out

Return Value

bit - Function return value

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_adapter.jal


_ERROR - JAL Language Syntax Reference

_ERROR JALV2 SYNTAX

Syntax

_ERROR "..."

Description

Generates a compiler error message. The compilation will fail with this error.

Notes

Can be used to prevent compilation under certain conditions.

Example

_ERROR "this function should not be used"

Generated by JAL Syntax Documentation System | Source: DITA


_WARN - JAL Language Syntax Reference

_WARN JALV2 SYNTAX

Syntax

_WARN "..."

Description

Generates a compiler warning message.

Notes

Useful for deprecation warnings or configuration checks.

Example

IF !DEFINED(foo) THEN
    _WARN "foo is not defined"
END IF

Generated by JAL Syntax Documentation System | Source: DITA


Aliases - JAL Language Syntax Reference

Aliases JALV2 SYNTAX

Description

Aliases allow a multiple identifiers (variables, named constants, sub-programs) to refer to the same object. The format for defining an alias is: Often it is useful to allow a variable or constant be referred to by multiple names. For example, if on a certain project pin_a1 is a red LED, you might prefer to refer to it as RED_LED. That way if, on a different project pin_a2 is the red LED, you'd need only change the alias and everything else would continue to work fine.

Generated by JAL Syntax Documentation System | Source: DITA


BLOCK - JAL Language Syntax Reference

BLOCK JALV2 SYNTAX

Syntax

BLOCK

Description

statement_block END BLOCK Creates a new block. Any variables deﬁned in this block go out of scope at the block. Mainly useful with the CASE statement (below).

Generated by JAL Syntax Documentation System | Source: DITA


bmp085_return_temperature_and_pressure_fast - JALlib Procedures Help

bmp085_return_temperature_and_pressure_fast JALLIB PROCEDURE

Signature

procedure bmp085_return_temperature_and_pressure_fast(byte in mode, sword out temperature, dword out pressure, bit out success) is

Description

Fast pressure measurement. Temperature is measured once in 128 times.
If constant cycle, once per second

Include

To use this procedure, include the library:

include bmp085

Parameters

  • mode - byte in
  • temperature - sword out
  • pressure - dword out
  • success - bit out

Return Value

None

Example

From sample file: 16f1519_bmp085.jal

-- Title: Sample file of using Bosch pressure sensor
-- Author: Urmas Joeleht, Copyright (c) 2014..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample program for use of BMP085 ressure sensor with Microchip PIC16lf1516.
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 29. Oct 2014 17:49:36.
--
-- ------------------------------------------------------
--
include 16f1519

pragma target clock 16_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
OSCCON_IRCF = 0b1111                -- 16_000_000 Hz
pragma target WDT      disabled     -- no watchdog
pragma target LVP      enabled      -- allow Low Voltage Programming
pragma target MCLR     external     -- reset externally
--
enable_digital_io()
alias   led      is pin_c1
pin_c1_direction =  output

include delay
include print
------------------------------
--SERIAL HW
------------------------------
const serial_hw_baudrate = 115_200
var bit serial_ctsinv
const serial_overflow_discard = false
const   SERIAL_XMTBUFSIZE  = 255
const   SERIAL_RCVBUFSIZE  = 1
const   SERIAL_DELTA       = 1
include serial_hardware

serial_hw_init()
------------------------------
--I2C software
------------------------------
alias i2c_scl is pin_d1
alias i2c_scl_direction is pin_d1_direction
alias i2c_sda is pin_d0
alias i2c_sda_direction is pin_d0_direction
var byte _i2c_bus_speed = 1
const bit _i2c_level = true   ; i2c levels (not SMB)
include i2c_software
i2c_initialize()
var byte i2c_tx_buffer[2]
var byte i2c_rx_buffer[2]
include i2c_level1
------------------------------
--BMP085
------------------------------
-- comment out next 3 lines if not using eoc pin (End Of Conversation)
-- If not using EOC  pin, program waits max conversation time, to be sure
-- conversation is ended
alias pin_eoc is pin_d4                       --Optional
alias pin_eoc_direction is pin_d4_direction   --Optional
pin_eoc_direction = input                     --Optional

include bmp085
var bit ok
bmp085_init(ok)
------------------------------
--variables for sample
------------------------------
var byte mode_string[] = "Mode: "
var byte temp_string[] = "Temperature: "
var byte press_string[] = "Pressure: "
var byte correct_string[] = "Data "
var byte ok_string[] = "Ok"
var byte nok_string[] = "Not Ok"
var sword tmp
var dword prs
var bit success
var byte mode -- for testing purposes
-----------------------------
-- Forever loop
-- After 1 second program asks temperature and pressure from chip with different mode setting.
-----------------------------
forever loop
   if mode >= 3 then
      mode = 0
   else
      mode = mode + 1
   end if
   bmp085_return_temperature_and_pressure_fast (mode, tmp, prs, success)
   print_string(serial_hw_data,mode_string)
   print_byte_dec(serial_hw_data,mode)
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,temp_string)
   print_sword_dec(serial_hw_data,tmp)
   serial_hw_data = "C"
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,press_string)
   print_dword_dec(serial_hw_data,prs)
   serial_hw_data = "P"
   serial_hw_data = "a"
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,correct_string)
   if success == 1 then
      print_string(serial_hw_data,ok_string)
   else
      print_string(serial_hw_data,nok_string)
   end if
   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)
   led = !led
   delay_1s(1)
end loop

Generated by JALlib CHM Help System | Source: bmp085.jal


can_check_uart_rx - JALlib Procedures Help

can_check_uart_rx JALLIB PROCEDURE

Signature

procedure can_check_uart_rx(volatile byte out device, byte in ch) is

Description

this routine is used to process incoming characters from the UART.
the data stream is line-oriented ASCII, with a CR(13) terminator.
sometimes the data is a command, which may need a reply back out
the UART. But most of the time, the data is encapsulated CAN messages
which need to be sent out the CANbus.
device: uart data device, e.g. serial_hw_data
ch: received ASCII char from UART

Include

To use this procedure, include the library:

include can_adapter

Parameters

  • device - byte out
  • ch - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_adapter.jal


can_green_1flash - JALlib Procedures Help

can_green_1flash JALLIB PROCEDURE

Signature

procedure can_green_1flash() is

Description

green led: 1 200ms flash

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_green_2flash - JALlib Procedures Help

can_green_2flash JALLIB PROCEDURE

Signature

procedure can_green_2flash() is

Description

green led: 2 200ms flashes

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_green_3flash - JALlib Procedures Help

can_green_3flash JALLIB PROCEDURE

Signature

procedure can_green_3flash() is

Description

green led: 3 200ms flashes

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_green_blink - JALlib Procedures Help

can_green_blink JALLIB PROCEDURE

Signature

procedure can_green_blink() is

Description

green led: blink 200ms off, 200ms on

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_green_off - JALlib Procedures Help

can_green_off JALLIB PROCEDURE

Signature

procedure can_green_off() is

Description

green led: off

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_green_on - JALlib Procedures Help

can_green_on JALLIB PROCEDURE

Signature

procedure can_green_on() is

Description

green led: on steady

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_is_std_id - JALlib Procedures Help

can_is_std_id JALLIB FUNCTION

Signature

function can_is_std_id(dword in can_id) return bit is

Description

No description available.

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • can_id - dword in

Return Value

bit - Function return value

Example

From sample file: 16f819_mcp2515_can_monitor.jal

-- Title: CAN bus monitor for STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Monitor CAN bus, using can_mpc2515 library.
--
-- Our monitor can be configured to either participate with ACKs
-- (normal mode), or operate in 'listen-only' mode.
--
-- In order for CAN bus hardware to work properly, there must
-- be at least two active nodes on the bus.
--
-- So, in listen-only mode, you will need at least two other nodes
-- or the CAN bus will not operate.
--
-- This file has been generated by hand (manually maintained)
--
include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "  CAN monitor"

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

alias can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)

-- just an example of how we can route frames to different buffers
can_write(CAN_RXB0CTRL, 0x40) -- extended frames here
can_write(CAN_RXB1CTRL, 0x00) -- standard frames here

can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)

can_write(CANCTRL, 0x07) -- Normal mode

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_msg
   var byte a,b,c,d, i, len
   var byte rxdata[8]
   var dword can_id

   a = can_read_status()
   b = can_rx_status()
   c = can_read(CAN_RXB0CTRL)
   d = can_read(CAN_RXB1CTRL)

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   lcd_cursor_position(1,0)
   print_byte_hex(lcd, a)
   lcd = " "
   print_byte_hex(lcd, b)
   lcd = " "
   print_byte_hex(lcd, c)
   lcd = " "
   print_byte_hex(lcd, d)
   lcd = " "

   -- check for a message
   if led != 0 then
      got_msg = can_receive(0, can_id, rxdata, len)
   else
      got_msg = can_receive(1, can_id, rxdata, len)
   end if

   if got_msg then
      if can_is_std_id(can_id) then
         lcd_cursor_position(2,0)
      else
         lcd_cursor_position(3,0)
      end if
      print_dword_hex(lcd, can_id)
      lcd = " "
      for 8 using i loop
         var byte v
         if i < len then
            print_byte_hex(lcd, rxdata[i])
         else
            lcd = " "
            lcd = " "
         end if
      end loop
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_led_delay100ms - JALlib Procedures Help

can_led_delay100ms JALLIB PROCEDURE

Signature

procedure can_led_delay100ms(word in n) is

Description

Delays for n * 100 mSec, while maintaining CAN leds

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

  • n - word in

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_led_poll - JALlib Procedures Help

can_led_poll JALLIB PROCEDURE

Signature

procedure can_led_poll() is

Description

implements blinking of CAN leds. call this routine somewhere in your main loop.
can led blink states are typically 200ms each, so try to call more often than 200ms.

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_legacy.jal - JALLIB Library Documentation

can_legacy.jal JALLIB LIBRARY

Title

Legacy internal CAN controller

Author

William Welch Copyright (c) 2009, all rights reserved.

Compiler

2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

-- The early 18C/F family had an internal CAN controller that was
very similar to the MCP2515. More recent devices have an ECAN controller which
has many enhanced features, but defaults on power-up to a 'legacy' mode.
N.B. This library has only been tested so far with the 18F2585 device.

the CAN ID uses the same 32-bit unsigned int format as the socket-CAN C library
bit 0-28 : CAN identifier (11/29 bit)
bit 29 : error frame flag (0 = data frame, 1 = error frame)
bit 30 : remote transmission request flag (1 = rtr frame)
bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)

Routines

  • can_encode_ext_id - Procedure
  • can_encode_rtr_id - Procedure
  • can_encode_std_id - Procedure
  • can_is_error_id - Function returns bit
  • can_is_ext_id - Function returns bit
  • can_is_rtr_id - Function returns bit
  • can_is_std_id - Function returns bit
  • can_receive - Function returns bit
  • can_reset - Procedure
  • can_send - Function returns bit
  • can_set_config - Procedure
  • can_set_rxb0_filter0 - Procedure
  • can_set_rxb0_filter1 - Procedure
  • can_set_rxb0_mask - Procedure
  • can_set_rxb1_filter2 - Procedure
  • can_set_rxb1_filter3 - Procedure
  • can_set_rxb1_filter4 - Procedure
  • can_set_rxb1_filter5 - Procedure
  • can_set_rxb1_mask - Procedure


can_mcp2515.jal - JALLIB Library Documentation

can_mcp2515.jal JALLIB LIBRARY

Title

External mcp2515 CAN controller

Author

William Welch Copyright (c) 2009, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

-- The MCP2515 is an external CAN controller with Slave SPI
interface. The controller has 3 transmit buffers and 2 receive buffers.
Note: uses SPI Master library and also needs a 'chip select' pin such as:
alias can_sel is pin_B0

Three transmit buffers. Each transmit buffer has a control register, header
registers, length register and (up to ) eight bytes of payload.

Routines

  • can_encode_ext_id - Procedure
  • can_encode_rtr_id - Procedure
  • can_encode_std_id - Procedure
  • can_is_error_id - Function returns bit
  • can_is_ext_id - Function returns bit
  • can_is_rtr_id - Function returns bit
  • can_is_std_id - Function returns bit
  • can_read - Function returns byte
  • can_read_status - Function returns byte
  • can_receive - Function returns bit
  • can_reset - Procedure
  • can_rx_status - Function returns byte
  • can_send - Function returns bit
  • can_set_config - Procedure
  • can_set_rxb0_filter0 - Procedure
  • can_set_rxb0_filter1 - Procedure
  • can_set_rxb0_mask - Procedure
  • can_set_rxb1_filter2 - Procedure
  • can_set_rxb1_filter3 - Procedure
  • can_set_rxb1_filter4 - Procedure
  • can_set_rxb1_filter5 - Procedure
  • can_set_rxb1_mask - Procedure
  • can_write - Procedure


can_read - JALlib Procedures Help

can_read JALLIB FUNCTION

Signature

function can_read(byte in addr) return byte is

Description

mcp2515 read instruction (single byte)
returns the current value of the specified register

Include

To use this procedure, include the library:

include can_mcp2515

Parameters

  • addr - byte in

Return Value

byte - Function return value

Example

From sample file: 16f819_mcp2515_canid4_monitor.jal

-- Title: CAN bus monitor for STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Monitor CAN bus, using can_mpc2515 library.
--
-- Our monitor can be configured to either participate with ACKs
-- (normal mode), or operate in 'listen-only' mode.
--
-- In order for CAN bus hardware to work properly, there must
-- be at least two active nodes on the bus.
--
-- So, in listen-only mode, you will need at least two other nodes
-- or the CAN bus will not operate.
--
-- This file has been generated by hand (manually maintained)
--
include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "  MON: 4 CAN-IDs"

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

alias can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)

-- just an example of how we can route frames to different buffers
can_write(CAN_RXB0CTRL, 0x40) -- extended frames here
can_write(CAN_RXB1CTRL, 0x00) -- standard frames here

can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)

can_write(CANCTRL, 0x07) -- Normal mode

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_msg
   var byte a,b,c,d, i, len
   var byte rxdata[8]
   var byte hb[4]
   var dword can_id

   a = can_read_status()
   b = can_rx_status()
   c = can_read(CAN_RXB0CTRL)
   d = can_read(CAN_RXB1CTRL)

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   -- lcd_cursor_position(1,0)
   -- print_byte_hex(lcd, a)
   -- lcd = " "
   -- print_byte_hex(lcd, b)
   -- lcd = " "
   -- print_byte_hex(lcd, c)
   -- lcd = " "
   -- print_byte_hex(lcd, d)
   -- lcd = " "

   -- check for a message
   if led != 0 then
      got_msg = can_receive(0, can_id, rxdata, len)
   else
      got_msg = can_receive(1, can_id, rxdata, len)
   end if

   if got_msg then
      var byte row
      row = byte(can_id) & 3

      lcd_cursor_position(row,0)
      -- print only the low 8-bits of CAN-ID
      print_byte_hex(lcd, byte(can_id) )
      if (hb[row] & 1) != 0 then
         lcd = "/"
      else
         lcd = "-"
      end if
      hb[row] = hb[row] ^ 1

      for 8 using i loop
         var byte v
         if i < len then
            print_byte_hex(lcd, rxdata[i])
         else
            lcd = " "
            lcd = " "
         end if
      end loop
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_mcp2515.jal


can_read_status - JALlib Procedures Help

can_read_status JALLIB FUNCTION

Signature

function can_read_status() return byte is

Description

mcp2515 read status instruction

Include

To use this procedure, include the library:

include can_mcp2515

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f819_mcp2515_canid4_monitor.jal

-- Title: CAN bus monitor for STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Monitor CAN bus, using can_mpc2515 library.
--
-- Our monitor can be configured to either participate with ACKs
-- (normal mode), or operate in 'listen-only' mode.
--
-- In order for CAN bus hardware to work properly, there must
-- be at least two active nodes on the bus.
--
-- So, in listen-only mode, you will need at least two other nodes
-- or the CAN bus will not operate.
--
-- This file has been generated by hand (manually maintained)
--
include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "  MON: 4 CAN-IDs"

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

alias can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)

-- just an example of how we can route frames to different buffers
can_write(CAN_RXB0CTRL, 0x40) -- extended frames here
can_write(CAN_RXB1CTRL, 0x00) -- standard frames here

can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)

can_write(CANCTRL, 0x07) -- Normal mode

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_msg
   var byte a,b,c,d, i, len
   var byte rxdata[8]
   var byte hb[4]
   var dword can_id

   a = can_read_status()
   b = can_rx_status()
   c = can_read(CAN_RXB0CTRL)
   d = can_read(CAN_RXB1CTRL)

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   -- lcd_cursor_position(1,0)
   -- print_byte_hex(lcd, a)
   -- lcd = " "
   -- print_byte_hex(lcd, b)
   -- lcd = " "
   -- print_byte_hex(lcd, c)
   -- lcd = " "
   -- print_byte_hex(lcd, d)
   -- lcd = " "

   -- check for a message
   if led != 0 then
      got_msg = can_receive(0, can_id, rxdata, len)
   else
      got_msg = can_receive(1, can_id, rxdata, len)
   end if

   if got_msg then
      var byte row
      row = byte(can_id) & 3

      lcd_cursor_position(row,0)
      -- print only the low 8-bits of CAN-ID
      print_byte_hex(lcd, byte(can_id) )
      if (hb[row] & 1) != 0 then
         lcd = "/"
      else
         lcd = "-"
      end if
      hb[row] = hb[row] ^ 1

      for 8 using i loop
         var byte v
         if i < len then
            print_byte_hex(lcd, rxdata[i])
         else
            lcd = " "
            lcd = " "
         end if
      end loop
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_mcp2515.jal


can_receive - JALlib Procedures Help

can_receive JALLIB FUNCTION

Signature

function can_receive(byte in buf_no, dword out can_id, byte out buf[8], byte out len) return bit is

Description

receive CAN frame, sets can_id flag bits as to standard/extended, error, and remote.
Non-blocking -- function returns immediately if no message is available.
FIXME. this is ugly code

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • buf_no - byte in
  • can_id - dword out
  • buf[] - byte out
  • len - byte out

Return Value

bit - Function return value

Example

From sample file: 16f819_mcp2515_canid4_monitor.jal

-- Title: CAN bus monitor for STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Monitor CAN bus, using can_mpc2515 library.
--
-- Our monitor can be configured to either participate with ACKs
-- (normal mode), or operate in 'listen-only' mode.
--
-- In order for CAN bus hardware to work properly, there must
-- be at least two active nodes on the bus.
--
-- So, in listen-only mode, you will need at least two other nodes
-- or the CAN bus will not operate.
--
-- This file has been generated by hand (manually maintained)
--
include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "  MON: 4 CAN-IDs"

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

alias can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)

-- just an example of how we can route frames to different buffers
can_write(CAN_RXB0CTRL, 0x40) -- extended frames here
can_write(CAN_RXB1CTRL, 0x00) -- standard frames here

can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)

can_write(CANCTRL, 0x07) -- Normal mode

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_msg
   var byte a,b,c,d, i, len
   var byte rxdata[8]
   var byte hb[4]
   var dword can_id

   a = can_read_status()
   b = can_rx_status()
   c = can_read(CAN_RXB0CTRL)
   d = can_read(CAN_RXB1CTRL)

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   -- lcd_cursor_position(1,0)
   -- print_byte_hex(lcd, a)
   -- lcd = " "
   -- print_byte_hex(lcd, b)
   -- lcd = " "
   -- print_byte_hex(lcd, c)
   -- lcd = " "
   -- print_byte_hex(lcd, d)
   -- lcd = " "

   -- check for a message
   if led != 0 then
      got_msg = can_receive(0, can_id, rxdata, len)
   else
      got_msg = can_receive(1, can_id, rxdata, len)
   end if

   if got_msg then
      var byte row
      row = byte(can_id) & 3

      lcd_cursor_position(row,0)
      -- print only the low 8-bits of CAN-ID
      print_byte_hex(lcd, byte(can_id) )
      if (hb[row] & 1) != 0 then
         lcd = "/"
      else
         lcd = "-"
      end if
      hb[row] = hb[row] ^ 1

      for 8 using i loop
         var byte v
         if i < len then
            print_byte_hex(lcd, rxdata[i])
         else
            lcd = " "
            lcd = " "
         end if
      end loop
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_red_1flash - JALlib Procedures Help

can_red_1flash JALLIB PROCEDURE

Signature

procedure can_red_1flash() is

Description

red led: 1 200ms flash

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_red_2flash - JALlib Procedures Help

can_red_2flash JALLIB PROCEDURE

Signature

procedure can_red_2flash() is

Description

red led: 2 200ms flashes

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_red_3flash - JALlib Procedures Help

can_red_3flash JALLIB PROCEDURE

Signature

procedure can_red_3flash() is

Description

red led: 3 200ms flashes

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_red_4flash - JALlib Procedures Help

can_red_4flash JALLIB PROCEDURE

Signature

procedure can_red_4flash() is

Description

red led: 4 200ms flashes

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_red_blink - JALlib Procedures Help

can_red_blink JALLIB PROCEDURE

Signature

procedure can_red_blink() is

Description

red led: blink 200ms on, 200ms off

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_red_off - JALlib Procedures Help

can_red_off JALLIB PROCEDURE

Signature

procedure can_red_off() is

Description

red led: off

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_red_on - JALlib Procedures Help

can_red_on JALLIB PROCEDURE

Signature

procedure can_red_on() is

Description

red led: on steady

Include

To use this procedure, include the library:

include can_bicolor_leds

Parameters

None

Return Value

None

Example

From sample file: 18f4585_canopen_blink.jal

-- Title: Test CANopen blink routines
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: CANopen defines some specific LED blink sequences. Some of the sequences
--              are rather lengthy, so we use the timer0 interval library and non-blocking
--              delay routines.
--
-- This file has been generated by hand (manually maintained)
--

include 18f4585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                -- no watchdog

-- set all IO as digital
enable_digital_io()

const timer0_overflow_rate = 10 -- 10 Hz -> 100mS period
const DELAY_SLOTS = 2
include timer0_poll_interval
timer0_poll_init()

const CANLED_BLINK_INTERVAL_SLOT = 0
const CANLED_DELAY_INTERVAL_SLOT = 1
const CANLED_INTERVAL_100MS = 1
alias can_led     is pin_b1
alias can_led_dir is pin_b1_direction
include can_bicolor_leds

-- red: steady, no blink
can_red_on()
can_green_off()
can_led_delay100ms(50)

-- green: steady, no blink
can_red_off()
can_green_on()
can_led_delay100ms(50)

-- alternating blink red/green
can_red_blink()
can_green_blink()
can_led_delay100ms(50)

can_green_off()

-- single red flash
can_red_1flash()
can_led_delay100ms(100)

-- double red flash
can_red_2flash()
can_led_delay100ms(100)

-- triple
can_red_3flash()
can_led_delay100ms(100)

-- quad
can_red_4flash()
can_led_delay100ms(100)

can_red_off()

-- single green flash
can_green_1flash()
can_led_delay100ms(100)

-- double
can_green_2flash()
can_led_delay100ms(100)

-- triple. odd, but no quad green in spec...
can_green_3flash()
can_led_delay100ms(100)

-- single red flash, with blinking green.
can_green_blink()
can_red_1flash()

forever loop
   -- keep those leds flashing and blinking
   can_led_poll()
end loop

Generated by JALlib CHM Help System | Source: can_bicolor_leds.jal


can_reset - JALlib Procedures Help

can_reset JALLIB PROCEDURE

Signature

procedure can_reset() is

Description

No description available.

Include

To use this procedure, include the library:

include can_legacy

Parameters

None

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_rx_status - JALlib Procedures Help

can_rx_status JALLIB FUNCTION

Signature

function can_rx_status() return byte is

Description

mcp2515 RX status instruction

Include

To use this procedure, include the library:

include can_mcp2515

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f819_mcp2515_canid4_monitor.jal

-- Title: CAN bus monitor for STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Monitor CAN bus, using can_mpc2515 library.
--
-- Our monitor can be configured to either participate with ACKs
-- (normal mode), or operate in 'listen-only' mode.
--
-- In order for CAN bus hardware to work properly, there must
-- be at least two active nodes on the bus.
--
-- So, in listen-only mode, you will need at least two other nodes
-- or the CAN bus will not operate.
--
-- This file has been generated by hand (manually maintained)
--
include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "  MON: 4 CAN-IDs"

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

alias can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)

-- just an example of how we can route frames to different buffers
can_write(CAN_RXB0CTRL, 0x40) -- extended frames here
can_write(CAN_RXB1CTRL, 0x00) -- standard frames here

can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)

can_write(CANCTRL, 0x07) -- Normal mode

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_msg
   var byte a,b,c,d, i, len
   var byte rxdata[8]
   var byte hb[4]
   var dword can_id

   a = can_read_status()
   b = can_rx_status()
   c = can_read(CAN_RXB0CTRL)
   d = can_read(CAN_RXB1CTRL)

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   -- lcd_cursor_position(1,0)
   -- print_byte_hex(lcd, a)
   -- lcd = " "
   -- print_byte_hex(lcd, b)
   -- lcd = " "
   -- print_byte_hex(lcd, c)
   -- lcd = " "
   -- print_byte_hex(lcd, d)
   -- lcd = " "

   -- check for a message
   if led != 0 then
      got_msg = can_receive(0, can_id, rxdata, len)
   else
      got_msg = can_receive(1, can_id, rxdata, len)
   end if

   if got_msg then
      var byte row
      row = byte(can_id) & 3

      lcd_cursor_position(row,0)
      -- print only the low 8-bits of CAN-ID
      print_byte_hex(lcd, byte(can_id) )
      if (hb[row] & 1) != 0 then
         lcd = "/"
      else
         lcd = "-"
      end if
      hb[row] = hb[row] ^ 1

      for 8 using i loop
         var byte v
         if i < len then
            print_byte_hex(lcd, rxdata[i])
         else
            lcd = " "
            lcd = " "
         end if
      end loop
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_mcp2515.jal


can_send - JALlib Procedures Help

can_send JALLIB FUNCTION

Signature

function can_send(byte in buf_no, dword in can_id, byte in buf[8], byte in len) return bit is

Description

send CAN frame
Non-blocking -- function returns immediately if buffer is busy (in-use)
FIXME. this is ugly code

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • buf_no - byte in
  • can_id - dword in
  • buf[] - byte in
  • len - byte in

Return Value

bit - Function return value

Example

From sample file: 18f2585_can_serial_hw.jal

-- Title: CAN to UART adapter example
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: gateway between RS232 and CAN bus. Uses ASCII encapsulation,
--          compatible with the Socket-CAN SLCAN API.
--
-- Sources: Socket-CAN, in particular the SLCAN API. http://developer.berlios.de/projects/socketcan/
--          also, the LAWICEL CAN-USB adapter.
--
-- For this example, the UART is only running at 9600. You may wish to increase to 115200 and re-test.
--
-- This file has been generated by hand (manually maintained)
--

include 18f2585
pragma target clock 16_000_000
pragma target OSC  HS_PLL
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

enable_digital_io()

var bit led is pin_A0
pin_A0_direction =  output

const usart_hw_serial = true
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- 125K bps
can_set_config(3, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- match all msgs
can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;
CANCON = 0; -- normal mode

-- gateway loop

var byte s_rxcnt, s_rxbuf[32]
var byte s_txcnt, s_txbuf[32]
s_rxcnt = 0

forever loop
   var bit got_msg, txstat
   var byte i, data_len, c
   var byte can_data[8]
   var dword can_id

   got_msg = can_receive(1, can_id, can_data, data_len)

   if got_msg then
      s_txcnt = can_to_ascii(can_id, can_data, data_len, s_txbuf)
      for s_txcnt using i loop
         serial_hw_data = s_txbuf[i]
      end loop
      -- serial_hw_data = 10
   end if

   if serial_hw_read(c) then
      s_rxbuf[s_rxcnt] = c
      s_rxcnt = s_rxcnt + 1
      if s_rxcnt >= 32 then
         s_rxcnt = 0
      end if
      if c == 13 then
         if ascii_to_can(s_rxbuf, can_id, can_data, data_len) then
            -- FIXME: should retry can_send if busy
            txstat = can_send(0, can_id, can_data, data_len)
         end if
         s_rxcnt = 0
      end if
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_config - JALlib Procedures Help

can_set_config JALLIB PROCEDURE

Signature

procedure can_set_config(byte in p1, byte in p2, byte in p3) is

Description

set bit-rate and related can bus configuration.
see datasheet for details.
N.B. The chip must already be in 'configuration mode'.

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • p1 - byte in
  • p2 - byte in
  • p3 - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb0_filter0 - JALlib Procedures Help

can_set_rxb0_filter0 JALLIB PROCEDURE

Signature

procedure can_set_rxb0_filter0(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RXB0 acceptance filter #0

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb0_filter1 - JALlib Procedures Help

can_set_rxb0_filter1 JALLIB PROCEDURE

Signature

procedure can_set_rxb0_filter1(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RXB0 acceptance filter #1

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb0_mask - JALlib Procedures Help

can_set_rxb0_mask JALLIB PROCEDURE

Signature

procedure can_set_rxb0_mask(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RX acceptance mask for buffer RXB0
N.B. calling with 0,0,0,0 will pass all messages

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb1_filter2 - JALlib Procedures Help

can_set_rxb1_filter2 JALLIB PROCEDURE

Signature

procedure can_set_rxb1_filter2(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RXB1 acceptance filter #2

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb1_filter3 - JALlib Procedures Help

can_set_rxb1_filter3 JALLIB PROCEDURE

Signature

procedure can_set_rxb1_filter3(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RXB1 acceptance filter #3

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb1_filter4 - JALlib Procedures Help

can_set_rxb1_filter4 JALLIB PROCEDURE

Signature

procedure can_set_rxb1_filter4(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RXB1 acceptance filter #4

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb1_filter5 - JALlib Procedures Help

can_set_rxb1_filter5 JALLIB PROCEDURE

Signature

procedure can_set_rxb1_filter5(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RXB1 acceptance filter #5

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_set_rxb1_mask - JALlib Procedures Help

can_set_rxb1_mask JALLIB PROCEDURE

Signature

procedure can_set_rxb1_mask(byte in sidh, byte in sidl, byte in eidh, byte in eidl) is

Description

set RX acceptance mask for buffer RXB1
N.B. calling with 0,0,0,0 will pass all messages

Include

To use this procedure, include the library:

include can_legacy

Parameters

  • sidh - byte in
  • sidl - byte in
  • eidh - byte in
  • eidl - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: can_legacy.jal


can_to_ascii - JALlib Procedures Help

can_to_ascii JALLIB FUNCTION

Signature

function can_to_ascii(dword in can_id, byte in can_data[8], byte in data_len, byte out ascii_buf[32]) return byte is

Description

convert CAN message to socket-CAN SLCAN API
FIXME: poor method.

Include

To use this procedure, include the library:

include can_ascii

Parameters

  • can_id - dword in
  • can_data[] - byte in
  • data_len - byte in
  • ascii_buf[] - byte out

Return Value

byte - Function return value

Example

From sample file: 18f2585_can_serial_hw.jal

-- Title: CAN to UART adapter example
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Adapted by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: gateway between RS232 and CAN bus. Uses ASCII encapsulation,
--          compatible with the Socket-CAN SLCAN API.
--
-- Sources: Socket-CAN, in particular the SLCAN API. http://developer.berlios.de/projects/socketcan/
--          also, the LAWICEL CAN-USB adapter.
--
-- For this example, the UART is only running at 9600. You may wish to increase to 115200 and re-test.
--
-- This file has been generated by hand (manually maintained)
--

include 18f2585
pragma target clock 16_000_000
pragma target OSC  HS_PLL
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

enable_digital_io()

var bit led is pin_A0
pin_A0_direction =  output

const usart_hw_serial = true
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- 125K bps
can_set_config(3, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- match all msgs
can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;
CANCON = 0; -- normal mode

-- gateway loop

var byte s_rxcnt, s_rxbuf[32]
var byte s_txcnt, s_txbuf[32]
s_rxcnt = 0

forever loop
   var bit got_msg, txstat
   var byte i, data_len, c
   var byte can_data[8]
   var dword can_id

   got_msg = can_receive(1, can_id, can_data, data_len)

   if got_msg then
      s_txcnt = can_to_ascii(can_id, can_data, data_len, s_txbuf)
      for s_txcnt using i loop
         serial_hw_data = s_txbuf[i]
      end loop
      -- serial_hw_data = 10
   end if

   if serial_hw_read(c) then
      s_rxbuf[s_rxcnt] = c
      s_rxcnt = s_rxcnt + 1
      if s_rxcnt >= 32 then
         s_rxcnt = 0
      end if
      if c == 13 then
         if ascii_to_can(s_rxbuf, can_id, can_data, data_len) then
            -- FIXME: should retry can_send if busy
            txstat = can_send(0, can_id, can_data, data_len)
         end if
         s_rxcnt = 0
      end if
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_ascii.jal


can_write - JALlib Procedures Help

can_write JALLIB PROCEDURE

Signature

procedure can_write(byte in addr, byte in data) is

Description

mcp2515 write instruction (single byte)
writes the value to the specified register

Include

To use this procedure, include the library:

include can_mcp2515

Parameters

  • addr - byte in
  • data - byte in

Return Value

None

Example

From sample file: 16f819_mcp2515_canid4_monitor.jal

-- Title: CAN bus monitor for STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Monitor CAN bus, using can_mpc2515 library.
--
-- Our monitor can be configured to either participate with ACKs
-- (normal mode), or operate in 'listen-only' mode.
--
-- In order for CAN bus hardware to work properly, there must
-- be at least two active nodes on the bus.
--
-- So, in listen-only mode, you will need at least two other nodes
-- or the CAN bus will not operate.
--
-- This file has been generated by hand (manually maintained)
--
include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "  MON: 4 CAN-IDs"

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

alias can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)

-- just an example of how we can route frames to different buffers
can_write(CAN_RXB0CTRL, 0x40) -- extended frames here
can_write(CAN_RXB1CTRL, 0x00) -- standard frames here

can_set_rxb0_mask(0,0,0,0)
can_set_rxb1_mask(0,0,0,0)

can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)

can_write(CANCTRL, 0x07) -- Normal mode

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_msg
   var byte a,b,c,d, i, len
   var byte rxdata[8]
   var byte hb[4]
   var dword can_id

   a = can_read_status()
   b = can_rx_status()
   c = can_read(CAN_RXB0CTRL)
   d = can_read(CAN_RXB1CTRL)

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   -- lcd_cursor_position(1,0)
   -- print_byte_hex(lcd, a)
   -- lcd = " "
   -- print_byte_hex(lcd, b)
   -- lcd = " "
   -- print_byte_hex(lcd, c)
   -- lcd = " "
   -- print_byte_hex(lcd, d)
   -- lcd = " "

   -- check for a message
   if led != 0 then
      got_msg = can_receive(0, can_id, rxdata, len)
   else
      got_msg = can_receive(1, can_id, rxdata, len)
   end if

   if got_msg then
      var byte row
      row = byte(can_id) & 3

      lcd_cursor_position(row,0)
      -- print only the low 8-bits of CAN-ID
      print_byte_hex(lcd, byte(can_id) )
      if (hb[row] & 1) != 0 then
         lcd = "/"
      else
         lcd = "-"
      end if
      hb[row] = hb[row] ^ 1

      for 8 using i loop
         var byte v
         if i < len then
            print_byte_hex(lcd, rxdata[i])
         else
            lcd = " "
            lcd = " "
         end if
      end loop
   end if

   led = led ^ 1
end loop

Generated by JALlib CHM Help System | Source: can_mcp2515.jal


canopen.jal - JALLIB Library Documentation

canopen.jal JALLIB LIBRARY

Title

CANopen library

Author

William Welch Copyright (c) 2009, all rights reserved.

Compiler

2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

-- a small CAN library compatible with CANopen

Sources

Cia DS 301 version 4.02

Note that we are using dword (32-bit) for cob_id for socket-CAN compatibility.

FIXME: how to truly support 'extended' 29-bit CAN identifiers?

format the COB-ID, which is a 'standard' 11-bit CAN identifier.
the function code is upper 4 bits, the node_id is lower 7 bits.

Routines

  • co_decode_cob_id - Procedure
  • co_encode_cob_id - Procedure
  • co_receive - Procedure
  • co_send - Procedure


cc1101_config_433_92mhz_100kbaud - JALlib Procedures Help

cc1101_config_433_92mhz_100kbaud JALLIB PROCEDURE

Signature

procedure cc1101_config_433_92mhz_100kbaud() is

Description

Rf settings - 100k baud

Include

To use this procedure, include the library:

include transceiver_cc1101

Parameters

None

Return Value

None

Example

From sample file: 18f4620_transceiver_cc1101.jal

-- Title: transceiver cc1101 Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- This file has been generated by hand (manually maintained)
--
-- Description: This is an example for use of the TI cc1101 receiver.
--              Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
--              This device will also work in the 900mhz range.
--              Max device power is 10dBi
--
-- Notes: I am not an RF genius, do your own testing and check your RF laws.
--        Use SmartRF studio for other settings.
--
-- Sources:
-- https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0
--

include 18f4620                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b111                 -- 8 MHz
OSCTUNE_PLLEN = TRUE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

-- Define a led
alias led                       is pin_a0
alias led_direction             is pin_a0_direction
led_direction = output

include delay
include print
include format

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

print_string(serial_data,"Program Started.")
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- Configure cc1101
const byte CC1101_BUF_SIZE = 20
--
alias cc1101_chip_select is pin_a1
alias cc1101_chip_select_direction is pin_a1_direction
alias cc1101_gdo0 is pin_a2
alias cc1101_gdo0_direction is pin_a2_direction
--
include transceiver_cc1101
cc1101_init()
;cc1101_config_433_92__1_2_kb()
cc1101_config_433_92mhz_100kbaud()
;cc1101_config_433_92mhz_250kbaud()
cc1101_tx_10dbi()

--
if cc1101_has_error == TRUE then
   print_string(serial_data, "ERROR LOADING CC1101\r\n")
else
   print_string(serial_data, "CC1101 Loaded OK\r\n")
end if

-- main program

-- Called when a good packet is received.
procedure cc1101_good_packet_received_callback(byte in packet_size) is
   print_byte_dec(serial_data,packet_size)
   serial_data = " "
   serial_data = " "
   serial_data = " "
   var byte step = 0
   for packet_size using step loop
      serial_data = " "
      print_byte_hex(serial_data,cc1101_rx_buffer[step])
   end loop
   print_crlf(serial_data)
end procedure
--
-- Called when a bad packet is received.
procedure cc1101_bad_packet_received_callback(byte in error) is
   if error == 0 then
      print_string(serial_data,"ERROR 0: CRC ERROR\r\n");
   elsif error == 1 then
      print_string(serial_data,"ERROR 1: RX buffer overflowed, RX buffer has been cleard.\r\n")
   elsif error == 2 then
      print_string(serial_data,"ERROR 2: RX buffer overflowed, RX buffer has been cleard.\r\n")
   end if
end procedure

forever loop
;   -- TX:
;   var byte i
;   i = 0
;   for 10 using i loop
;      cc1101_tx_buffer[i] = i
;   end loop
;
;   forever loop
;      led = !led
;      delay_1ms(250);
;
;      cc1101_send_packet(10);
;      serial_data = "."
;   end loop

   -- RX:
   forever loop
      -- Wait for new packets.
      cc1101_receive_packet()
      led = !led
   end loop
end loop

Generated by JALlib CHM Help System | Source: transceiver_cc1101.jal


cc1101_config_433_92mhz_250kbaud - JALlib Procedures Help

cc1101_config_433_92mhz_250kbaud JALLIB PROCEDURE

Signature

procedure cc1101_config_433_92mhz_250kbaud() is

Description

Rf settings - 250k baud
Smart RF Studio 7 Settings:
-- Base Frequency: 433.999969 MHz
-- Xtal: 26.000000 MHz
-- Modulation Format: 2-FSK
-- Channel Number: 0
-- Data Rate: 249.939 kBaud
-- Deviation: 126.953125 kHz
-- Channel Spacing: 199.951172 kHz
-- RF Filter BW: 650.000000 kHz
-- TX Power: 0dBm
-- Carrier Frequency: 433.999969 MHz
-- Manchester Enable: No
-- PA Ramping: No
-- Whitening: No

Include

To use this procedure, include the library:

include transceiver_cc1101

Parameters

None

Return Value

None

Example

From sample file: 18f4620_transceiver_cc1101.jal

-- Title: transceiver cc1101 Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- This file has been generated by hand (manually maintained)
--
-- Description: This is an example for use of the TI cc1101 receiver.
--              Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
--              This device will also work in the 900mhz range.
--              Max device power is 10dBi
--
-- Notes: I am not an RF genius, do your own testing and check your RF laws.
--        Use SmartRF studio for other settings.
--
-- Sources:
-- https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0
--

include 18f4620                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b111                 -- 8 MHz
OSCTUNE_PLLEN = TRUE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

-- Define a led
alias led                       is pin_a0
alias led_direction             is pin_a0_direction
led_direction = output

include delay
include print
include format

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

print_string(serial_data,"Program Started.")
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- Configure cc1101
const byte CC1101_BUF_SIZE = 20
--
alias cc1101_chip_select is pin_a1
alias cc1101_chip_select_direction is pin_a1_direction
alias cc1101_gdo0 is pin_a2
alias cc1101_gdo0_direction is pin_a2_direction
--
include transceiver_cc1101
cc1101_init()
;cc1101_config_433_92__1_2_kb()
cc1101_config_433_92mhz_100kbaud()
;cc1101_config_433_92mhz_250kbaud()
cc1101_tx_10dbi()

--
if cc1101_has_error == TRUE then
   print_string(serial_data, "ERROR LOADING CC1101\r\n")
else
   print_string(serial_data, "CC1101 Loaded OK\r\n")
end if

-- main program

-- Called when a good packet is received.
procedure cc1101_good_packet_received_callback(byte in packet_size) is
   print_byte_dec(serial_data,packet_size)
   serial_data = " "
   serial_data = " "
   serial_data = " "
   var byte step = 0
   for packet_size using step loop
      serial_data = " "
      print_byte_hex(serial_data,cc1101_rx_buffer[step])
   end loop
   print_crlf(serial_data)
end procedure
--
-- Called when a bad packet is received.
procedure cc1101_bad_packet_received_callback(byte in error) is
   if error == 0 then
      print_string(serial_data,"ERROR 0: CRC ERROR\r\n");
   elsif error == 1 then
      print_string(serial_data,"ERROR 1: RX buffer overflowed, RX buffer has been cleard.\r\n")
   elsif error == 2 then
      print_string(serial_data,"ERROR 2: RX buffer overflowed, RX buffer has been cleard.\r\n")
   end if
end procedure

forever loop
;   -- TX:
;   var byte i
;   i = 0
;   for 10 using i loop
;      cc1101_tx_buffer[i] = i
;   end loop
;
;   forever loop
;      led = !led
;      delay_1ms(250);
;
;      cc1101_send_packet(10);
;      serial_data = "."
;   end loop

   -- RX:
   forever loop
      -- Wait for new packets.
      cc1101_receive_packet()
      led = !led
   end loop
end loop

Generated by JALlib CHM Help System | Source: transceiver_cc1101.jal


cc1101_init - JALlib Procedures Help

cc1101_init JALLIB PROCEDURE

Signature

procedure cc1101_init() is

Description

Initialize

Include

To use this procedure, include the library:

include transceiver_cc1101

Parameters

None

Return Value

None

Example

From sample file: 18f4620_transceiver_cc1101.jal

-- Title: transceiver cc1101 Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- This file has been generated by hand (manually maintained)
--
-- Description: This is an example for use of the TI cc1101 receiver.
--              Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
--              This device will also work in the 900mhz range.
--              Max device power is 10dBi
--
-- Notes: I am not an RF genius, do your own testing and check your RF laws.
--        Use SmartRF studio for other settings.
--
-- Sources:
-- https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0
--

include 18f4620                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b111                 -- 8 MHz
OSCTUNE_PLLEN = TRUE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

-- Define a led
alias led                       is pin_a0
alias led_direction             is pin_a0_direction
led_direction = output

include delay
include print
include format

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

print_string(serial_data,"Program Started.")
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- Configure cc1101
const byte CC1101_BUF_SIZE = 20
--
alias cc1101_chip_select is pin_a1
alias cc1101_chip_select_direction is pin_a1_direction
alias cc1101_gdo0 is pin_a2
alias cc1101_gdo0_direction is pin_a2_direction
--
include transceiver_cc1101
cc1101_init()
;cc1101_config_433_92__1_2_kb()
cc1101_config_433_92mhz_100kbaud()
;cc1101_config_433_92mhz_250kbaud()
cc1101_tx_10dbi()

--
if cc1101_has_error == TRUE then
   print_string(serial_data, "ERROR LOADING CC1101\r\n")
else
   print_string(serial_data, "CC1101 Loaded OK\r\n")
end if

-- main program

-- Called when a good packet is received.
procedure cc1101_good_packet_received_callback(byte in packet_size) is
   print_byte_dec(serial_data,packet_size)
   serial_data = " "
   serial_data = " "
   serial_data = " "
   var byte step = 0
   for packet_size using step loop
      serial_data = " "
      print_byte_hex(serial_data,cc1101_rx_buffer[step])
   end loop
   print_crlf(serial_data)
end procedure
--
-- Called when a bad packet is received.
procedure cc1101_bad_packet_received_callback(byte in error) is
   if error == 0 then
      print_string(serial_data,"ERROR 0: CRC ERROR\r\n");
   elsif error == 1 then
      print_string(serial_data,"ERROR 1: RX buffer overflowed, RX buffer has been cleard.\r\n")
   elsif error == 2 then
      print_string(serial_data,"ERROR 2: RX buffer overflowed, RX buffer has been cleard.\r\n")
   end if
end procedure

forever loop
;   -- TX:
;   var byte i
;   i = 0
;   for 10 using i loop
;      cc1101_tx_buffer[i] = i
;   end loop
;
;   forever loop
;      led = !led
;      delay_1ms(250);
;
;      cc1101_send_packet(10);
;      serial_data = "."
;   end loop

   -- RX:
   forever loop
      -- Wait for new packets.
      cc1101_receive_packet()
      led = !led
   end loop
end loop

Generated by JALlib CHM Help System | Source: transceiver_cc1101.jal


cc1101_receive_packet - JALlib Procedures Help

cc1101_receive_packet JALLIB PROCEDURE

Signature

procedure cc1101_receive_packet() is

Description

Receive packet (fills array cc1101_rx_buffer[])

Include

To use this procedure, include the library:

include transceiver_cc1101

Parameters

None

Return Value

None

Example

From sample file: 18f4620_transceiver_cc1101.jal

-- Title: transceiver cc1101 Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- This file has been generated by hand (manually maintained)
--
-- Description: This is an example for use of the TI cc1101 receiver.
--              Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
--              This device will also work in the 900mhz range.
--              Max device power is 10dBi
--
-- Notes: I am not an RF genius, do your own testing and check your RF laws.
--        Use SmartRF studio for other settings.
--
-- Sources:
-- https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0
--

include 18f4620                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b111                 -- 8 MHz
OSCTUNE_PLLEN = TRUE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

-- Define a led
alias led                       is pin_a0
alias led_direction             is pin_a0_direction
led_direction = output

include delay
include print
include format

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

print_string(serial_data,"Program Started.")
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- Configure cc1101
const byte CC1101_BUF_SIZE = 20
--
alias cc1101_chip_select is pin_a1
alias cc1101_chip_select_direction is pin_a1_direction
alias cc1101_gdo0 is pin_a2
alias cc1101_gdo0_direction is pin_a2_direction
--
include transceiver_cc1101
cc1101_init()
;cc1101_config_433_92__1_2_kb()
cc1101_config_433_92mhz_100kbaud()
;cc1101_config_433_92mhz_250kbaud()
cc1101_tx_10dbi()

--
if cc1101_has_error == TRUE then
   print_string(serial_data, "ERROR LOADING CC1101\r\n")
else
   print_string(serial_data, "CC1101 Loaded OK\r\n")
end if

-- main program

-- Called when a good packet is received.
procedure cc1101_good_packet_received_callback(byte in packet_size) is
   print_byte_dec(serial_data,packet_size)
   serial_data = " "
   serial_data = " "
   serial_data = " "
   var byte step = 0
   for packet_size using step loop
      serial_data = " "
      print_byte_hex(serial_data,cc1101_rx_buffer[step])
   end loop
   print_crlf(serial_data)
end procedure
--
-- Called when a bad packet is received.
procedure cc1101_bad_packet_received_callback(byte in error) is
   if error == 0 then
      print_string(serial_data,"ERROR 0: CRC ERROR\r\n");
   elsif error == 1 then
      print_string(serial_data,"ERROR 1: RX buffer overflowed, RX buffer has been cleard.\r\n")
   elsif error == 2 then
      print_string(serial_data,"ERROR 2: RX buffer overflowed, RX buffer has been cleard.\r\n")
   end if
end procedure

forever loop
;   -- TX:
;   var byte i
;   i = 0
;   for 10 using i loop
;      cc1101_tx_buffer[i] = i
;   end loop
;
;   forever loop
;      led = !led
;      delay_1ms(250);
;
;      cc1101_send_packet(10);
;      serial_data = "."
;   end loop

   -- RX:
   forever loop
      -- Wait for new packets.
      cc1101_receive_packet()
      led = !led
   end loop
end loop

Generated by JALlib CHM Help System | Source: transceiver_cc1101.jal


cc1101_send_packet - JALlib Procedures Help

cc1101_send_packet JALLIB PROCEDURE

Signature

procedure cc1101_send_packet(byte in size) is

Description

Send data in cc1101_tx_buffer

Include

To use this procedure, include the library:

include transceiver_cc1101

Parameters

  • size - byte in

Return Value

None

Example

From sample file: 18f4620_transceiver_cc1101.jal

-- Title: transceiver cc1101 Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- This file has been generated by hand (manually maintained)
--
-- Description: This is an example for use of the TI cc1101 receiver.
--              Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
--              This device will also work in the 900mhz range.
--              Max device power is 10dBi
--
-- Notes: I am not an RF genius, do your own testing and check your RF laws.
--        Use SmartRF studio for other settings.
--
-- Sources:
-- https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0
--

include 18f4620                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b111                 -- 8 MHz
OSCTUNE_PLLEN = TRUE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

-- Define a led
alias led                       is pin_a0
alias led_direction             is pin_a0_direction
led_direction = output

include delay
include print
include format

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

print_string(serial_data,"Program Started.")
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- Configure cc1101
const byte CC1101_BUF_SIZE = 20
--
alias cc1101_chip_select is pin_a1
alias cc1101_chip_select_direction is pin_a1_direction
alias cc1101_gdo0 is pin_a2
alias cc1101_gdo0_direction is pin_a2_direction
--
include transceiver_cc1101
cc1101_init()
;cc1101_config_433_92__1_2_kb()
cc1101_config_433_92mhz_100kbaud()
;cc1101_config_433_92mhz_250kbaud()
cc1101_tx_10dbi()

--
if cc1101_has_error == TRUE then
   print_string(serial_data, "ERROR LOADING CC1101\r\n")
else
   print_string(serial_data, "CC1101 Loaded OK\r\n")
end if

-- main program

-- Called when a good packet is received.
procedure cc1101_good_packet_received_callback(byte in packet_size) is
   print_byte_dec(serial_data,packet_size)
   serial_data = " "
   serial_data = " "
   serial_data = " "
   var byte step = 0
   for packet_size using step loop
      serial_data = " "
      print_byte_hex(serial_data,cc1101_rx_buffer[step])
   end loop
   print_crlf(serial_data)
end procedure
--
-- Called when a bad packet is received.
procedure cc1101_bad_packet_received_callback(byte in error) is
   if error == 0 then
      print_string(serial_data,"ERROR 0: CRC ERROR\r\n");
   elsif error == 1 then
      print_string(serial_data,"ERROR 1: RX buffer overflowed, RX buffer has been cleard.\r\n")
   elsif error == 2 then
      print_string(serial_data,"ERROR 2: RX buffer overflowed, RX buffer has been cleard.\r\n")
   end if
end procedure

forever loop
;   -- TX:
;   var byte i
;   i = 0
;   for 10 using i loop
;      cc1101_tx_buffer[i] = i
;   end loop
;
;   forever loop
;      led = !led
;      delay_1ms(250);
;
;      cc1101_send_packet(10);
;      serial_data = "."
;   end loop

   -- RX:
   forever loop
      -- Wait for new packets.
      cc1101_receive_packet()
      led = !led
   end loop
end loop

Generated by JALlib CHM Help System | Source: transceiver_cc1101.jal


cc1101_tx_10dbi - JALlib Procedures Help

cc1101_tx_10dbi JALLIB PROCEDURE

Signature

procedure cc1101_tx_10dbi() is

Description

Set TX power to 10dbi

Include

To use this procedure, include the library:

include transceiver_cc1101

Parameters

None

Return Value

None

Example

From sample file: 18f4620_transceiver_cc1101.jal

-- Title: transceiver cc1101 Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- This file has been generated by hand (manually maintained)
--
-- Description: This is an example for use of the TI cc1101 receiver.
--              Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
--              This device will also work in the 900mhz range.
--              Max device power is 10dBi
--
-- Notes: I am not an RF genius, do your own testing and check your RF laws.
--        Use SmartRF studio for other settings.
--
-- Sources:
-- https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0
--

include 18f4620                     -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT           -- internal oscillator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCCON_IRCF = 0b111                 -- 8 MHz
OSCTUNE_PLLEN = TRUE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

-- Define a led
alias led                       is pin_a0
alias led_direction             is pin_a0_direction
led_direction = output

include delay
include print
include format

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

print_string(serial_data,"Program Started.")
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- Configure cc1101
const byte CC1101_BUF_SIZE = 20
--
alias cc1101_chip_select is pin_a1
alias cc1101_chip_select_direction is pin_a1_direction
alias cc1101_gdo0 is pin_a2
alias cc1101_gdo0_direction is pin_a2_direction
--
include transceiver_cc1101
cc1101_init()
;cc1101_config_433_92__1_2_kb()
cc1101_config_433_92mhz_100kbaud()
;cc1101_config_433_92mhz_250kbaud()
cc1101_tx_10dbi()

--
if cc1101_has_error == TRUE then
   print_string(serial_data, "ERROR LOADING CC1101\r\n")
else
   print_string(serial_data, "CC1101 Loaded OK\r\n")
end if

-- main program

-- Called when a good packet is received.
procedure cc1101_good_packet_received_callback(byte in packet_size) is
   print_byte_dec(serial_data,packet_size)
   serial_data = " "
   serial_data = " "
   serial_data = " "
   var byte step = 0
   for packet_size using step loop
      serial_data = " "
      print_byte_hex(serial_data,cc1101_rx_buffer[step])
   end loop
   print_crlf(serial_data)
end procedure
--
-- Called when a bad packet is received.
procedure cc1101_bad_packet_received_callback(byte in error) is
   if error == 0 then
      print_string(serial_data,"ERROR 0: CRC ERROR\r\n");
   elsif error == 1 then
      print_string(serial_data,"ERROR 1: RX buffer overflowed, RX buffer has been cleard.\r\n")
   elsif error == 2 then
      print_string(serial_data,"ERROR 2: RX buffer overflowed, RX buffer has been cleard.\r\n")
   end if
end procedure

forever loop
;   -- TX:
;   var byte i
;   i = 0
;   for 10 using i loop
;      cc1101_tx_buffer[i] = i
;   end loop
;
;   forever loop
;      led = !led
;      delay_1ms(250);
;
;      cc1101_send_packet(10);
;      serial_data = "."
;   end loop

   -- RX:
   forever loop
      -- Wait for new packets.
      cc1101_receive_packet()
      led = !led
   end loop
end loop

Generated by JALlib CHM Help System | Source: transceiver_cc1101.jal


characters.jal - JALLIB Library Documentation

characters.jal JALLIB LIBRARY

Title

Character Library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009-2014, all rights reserved., Adapted-by: Joep Suijs

Compiler

>=2.4k

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for managing characters.

Sources

------------------------------------------------------------------------------
convert an integer (0 to 9) to a single ascii character
------------------------------------------------------------------------------

Routines

  • char_compare - Function returns bit
  • char_int_to_ascii - Procedure
  • char_is_digit - Function returns bit
  • char_is_letter - Function returns bit
  • char_is_lower - Function returns bit
  • char_is_printable - Function returns bit
  • char_is_upper - Function returns bit
  • char_lower - Procedure
  • char_upper - Procedure


charlie.jal - JALLIB Library Documentation

charlie.jal JALLIB LIBRARY

Title

charlie.jal - Control charlieplexed led matrix

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q3

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

Control a matrix or array of charlieplexed leds.
Of a set of charlieplexed leds only one led can be on at a time. To display
a stable pattern formed by multiple on-leds the leds must be switched on and off
very quickly after each other such that the human eye won't notice the off-period.
This library takes care of this switching. The user-program only needs to provide
the pattern to be shown in the led matrix and some parameters describing the
physical configuration.
This library was developed with in mind Jimmie Rogers' LoL (Lots of Leds) shield
for the Arduino with 9x14 (126) leds controlled with 12 pins, but the library is
flexible enough to control other configurations of charlieplexed leds.
.
Before including this library some basic constants should be declared:
const byte CP_COLS -- number of leds in a row (default 14, max 16)
const byte CP_ROWS -- number of rows of leds (default 9)
const byte CP_FREQ -- led refresh frequency (default 40)
.
One or two dedicated ports are required, depending on the number of pins that
have to be controlled. For up to 56 leds a single port (8 pins) is sufficient.
With a larger number of leds a second port is required.
For the chosen ports an alias must be specified, for example:
alias cp_port1 is portA -- required first or only port (default portA)
alias cp_port2 is portC -- [optional] second port
Also corresponding aliases for the direction settings are required, like:
alias cp_port1_direction is portA_direction
alias cp_port2_direction is portC_direction
Because of performance reasons this library handles the assigned port(s)
exclusively. Unused pins may be usable for other purposes but for input only.
.
A const byte array CP_XY[CP_ROWS * CP_COLS] must be declared to describe the
matrix of charlieplexed leds. Each byte of the array represents one led and must
contain the pin-number of the '+'pin (source pin) in the higher nibble and the
pin-number of the '-'pin (sink pin) in the lower nibble.
Pin numbers 0..7 should be connected to <cp_port1> pins 0..7,
pin numbers 8..15 should be connected to <cp_port2> pins 0..7.
The required array may look like:
const byte CP_XY[CP_ROWS * CP_COLS] = { (3 << 4) | 1, -- source pin 3, sink pin 1
(2 << 4) | 9, -- source pin 2, sink pin 9
etc....
}
.
An array of words 'cp_pattern' must be declared for the pattern to be shown
in the led matrix. Each word represents a row of the led matrix.
The low order bit of the first word represents the first led of the first row,
the next higher order bit the second led in the row, and so on.
How this corresponds to the physical display depends of course on the
orientation of the led matrix and the contents of the CP_XY[] array.
var word cp_pattern[CP_ROWS]
This is most likely an array of which the elements will change over time.
It can be initialized with the declaration with all zeroes and be
filled later in the program, but may also contain an initial pattern.
For example to have 4 leds ON in the upper row of a matrix specify:
var word cp_pattern[CP_ROWS] = { 0b0000_0011_1100_0000, -- 1st row
0b0000_0000_0000_0000 -- 2nd row
etc.... -- for every row
}

Notes

- This library uses Timer0 and a Timer0 interrupt routine.
Don't touch TMR0IE and GIE. The leds are normally controlled with
a pretty high current for a very short time (low PWM duty cycle).
Interrupting the refresh cycle may damage the led matrix.
- The interrupt processing is quite intensive:
Each ON-bit requires (avg) about 300 processor cycles
(machine instructions), each OFF-bit about 60 cycles.
A high Fosc value is desired to leave enough cycles for the
'real' application! The more leds the stronger this requirement.
- Limitations: - Maximum colums: 16
- Maximum number of pins: 16
- A more flexible implementations with existing libraries like
pintools and timer0_isr_interval showed (much) heavier
processor load and memory usage.

--- basic parameters ---------------------------------

Sources

- Microchip Application note TB029.
- Site of Jimmie Rogers for a LoL ("Lots of Leds") shield for Arduino
(a 9x14 matrix of charlieplexed leds).

Constants and Variables

CP_COLS - const byte = 14
CP_ROWS - const byte = 9
CP_FREQ - const byte = 40

Routines

  • _charlie_timer0_isr - Procedure
  • charlie_init - Procedure


charlie_init - JALlib Procedures Help

charlie_init JALLIB PROCEDURE

Signature

procedure charlie_init() is

Description

Title: Initialize library: start the refresh process

Include

To use this procedure, include the library:

include charlie

Parameters

None

Return Value

None

Example

From sample file: 12f683_charlie_10leds.jal

-- ------------------------------------------------------
-- Title: Control 10 LEDs with 4 I/O pins
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Control a row of 10 charlieplexed leds, controlled with 4 pins.
-- In this example the 10 leds show the value of a counter in binary format.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- - Microchip Application note TB029.
--
-- Notes:
--
-- ------------------------------------------------------
--
include 12f683                                  -- target PICmicro
--
pragma target clock    8_000_000                -- oscillator frequency

-- configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT          -- internal oscillator
pragma target WDT      disabled                 -- watchdog software controlled
pragma target PWRTE    enabled                  -- power up delay
pragma target MCLR     internal                 -- make MCLR pin available I/O
pragma target BROWNOUT disabled                 -- no brownout
pragma target IESO     disabled                 -- no osc switch over
pragma target FCMEN    disabled                 -- no clock monitoring

OSCCON_IRCF = 0b111                             -- 8 MHz
OSCCON_SCS  = 0b00                              -- clock determined by fuses

enable_digital_io()                             -- disable analog I/O

include delay

-- --- setup for charlie library -----------------------------
--
const CP_COLS = 10                              -- 10 leds in a row
const CP_ROWS = 1                               -- single row
const CP_FREQ = 40                              -- refresh frequency (Hz)

-- --- led array connections ---------------------------------
-- Per led - upper nibble: source pin number
--         - lower nibble: sink pin number
-- Used pins: pin_A0,A1,A4,A5
--                                                            source  sink
const byte CP_XY[CP_COLS * CP_ROWS] = { 0x_4_1,           --    4      1
                                        0x_1_4,           --    1      4
                                        0x_4_0,           --    4      0
                                        0x_0_4,           --    0      4
                                        0x_5_1,           --    5      1
                                        0x_1_5,           --    1      5
                                        0x_5_0,           --    5      0
                                        0x_0_5,           --    0      5
                                        0x_5_4,           --    5      4
                                        0x_4_5            --    4      5
                                      }

-- --- led pattern (changed in mainline) ---------------------

var word cp_pattern[CP_ROWS] = { 0 }            -- single row

-- --- ports used by this board ------------------------------

alias cp_port1 is portA
alias cp_port1_direction is portA_direction

include charlie

charlie_init()

-- --- main line --------------------------

forever loop

   cp_pattern[0] = 0
   for 1024 loop                                -- 2^10
      delay_1ms(100)
      cp_pattern[0] = cp_pattern[0] + 1         -- binary counter
   end loop

end loop

Generated by JALlib CHM Help System | Source: charlie.jal


check_delay - JALlib Procedures Help

check_delay JALLIB FUNCTION

Signature

function check_delay(byte in slot) return bit is

Description

No description available.

Include

To use this procedure, include the library:

include timer0_isr_interval

Parameters

  • slot - byte in

Return Value

bit - Function return value

Example

From sample file: 18f14k50_timer0_interval.jal

-- ----------------------------------------------------------------------------
-- Title: test timer0 interval
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: test the library timero_isr_interval
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_timer0_interval.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

led_direction = output

if (defined(led2)) then -- compile only when led2 is defined.
   led2_direction = output
end if

-- set all IO as digital
enable_digital_io()

-- setup the timer0_isr_interval library
const word timer0_isr_rate = 1000  -- 1 kHz isr rate
const DELAY_SLOTS = 2         -- support 2 delays at the same time
include timer0_isr_interval
timer0_isr_init()             -- init timer0 isr

var word prev_interval_counter

   forever loop

      if (isr_counter != prev_interval_counter) then
         prev_interval_counter = isr_counter
         -- put here code that you want
         -- to execute each tick.
      end if ; 1 kHz loop

      if (check_delay(0)) then
         set_delay(0, 409) -- 409 ticks on delay-slot 0
         led = !led
      end if
      if (defined(led2)) then -- compile only when led2 is defined.
         if (check_delay(1)) then
            set_delay(1, 619) -- 619 ticks on delay-slot 1
            led2 = !led2
         end if
      end if
   end loop

; end of main

Generated by JALlib CHM Help System | Source: timer0_isr_interval.jal


checksum.jal - JALLIB Library Documentation

checksum.jal JALLIB LIBRARY

Title

Checksum

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library calculates checksums for data error detection.

Sources

http://www.faqs.org/rfcs/rfc1071.html

------------------------------------------------------------------------------
Computes a 16bit checksum from a byte array using every 2 bytes in the array.
Mostly used for IP header checksums.
------------------------------------------------------------------------------

Routines

  • checksum_16_byte_calc - Function returns word
  • checksum_16_byte_verify - Function returns bit


chipdef_jallib.jal - JALLIB Library Documentation

chipdef_jallib.jal JALLIB LIBRARY

Title

Common Jallib include file for device files

Author

Rob Hamerling, Rob Jansen, Copyright (c) 2008..2025 all rights reserved., Adapted-by: N/A (generated file, do not change!)

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Common Jallib include file for device files

Notes

- This file is generated by <pic2jal.py> script version 2.2
- File creation date/time: Sat Mar 22 19:15:13 2025
- Based on MPLABX v6.25
------------------------------------------------
JalV2 compiler required constants

Constants and Variables

PJAL - const bit = 1
W - const byte = 0
F - const byte = 1
PIC_10F200 - const word = 0xF200
PIC_10F202 - const word = 0xF202
PIC_10F204 - const word = 0xF204
PIC_10F206 - const word = 0xF206
PIC_10F220 - const word = 0xF220
PIC_10F222 - const word = 0xF222
PIC_10F320 - const word = 0xF320
PIC_10F322 - const word = 0xF322
PIC_10LF320 - const word = 0xA320
PIC_10LF322 - const word = 0xA322
PIC_12F1501 - const word = 0x1501
PIC_12F1571 - const word = 0x1571
PIC_12F1572 - const word = 0x1572
PIC_12F1612 - const word = 0x1612
PIC_12F1822 - const word = 0x1822
PIC_12F1840 - const word = 0x1840
PIC_12F508 - const word = 0xF508
PIC_12F509 - const word = 0xF509
PIC_12F510 - const word = 0xF510
PIC_12F519 - const word = 0xF519
PIC_12F609 - const word = 0xF609
PIC_12F615 - const word = 0xF615
PIC_12F617 - const word = 0xF617
PIC_12F629 - const word = 0x2629
PIC_12F635 - const word = 0xF635
PIC_12F675 - const word = 0x2675
PIC_12F683 - const word = 0xF683
PIC_12F752 - const word = 0xF752
PIC_12HV609 - const word = 0x6609
PIC_12HV615 - const word = 0x6615
PIC_12HV752 - const word = 0x6652
PIC_12LF1501 - const word = 0xA501
PIC_12LF1552 - const word = 0xA552
PIC_12LF1571 - const word = 0xA571
PIC_12LF1572 - const word = 0xA572
PIC_12LF1612 - const word = 0xA612
PIC_12LF1822 - const word = 0xA822
PIC_12LF1840 - const word = 0xA840
PIC_12LF1840T39A - const word = 0xC840
PIC_12LF1840T48A - const word = 0xB840
PIC_16F13113 - const word = 0xA36A
PIC_16F13114 - const word = 0xA369
PIC_16F13115 - const word = 0xA368
PIC_16F13123 - const word = 0xA367
PIC_16F13124 - const word = 0xA366
PIC_16F13125 - const word = 0xA365
PIC_16F13143 - const word = 0xA364
PIC_16F13144 - const word = 0xA363
PIC_16F13145 - const word = 0xA362
PIC_16F1454 - const word = 0x1454
PIC_16F1455 - const word = 0x1455
PIC_16F1459 - const word = 0x1459
PIC_16F1503 - const word = 0x1503
PIC_16F1507 - const word = 0x1507
PIC_16F1508 - const word = 0x1508
PIC_16F1509 - const word = 0x1509
PIC_16F1512 - const word = 0x1512
PIC_16F1513 - const word = 0x1513
PIC_16F1516 - const word = 0x1516
PIC_16F1517 - const word = 0x1517
PIC_16F1518 - const word = 0x1518
PIC_16F1519 - const word = 0x1519
PIC_16F15213 - const word = 0xA2FF
PIC_16F15214 - const word = 0xA300
PIC_16F15223 - const word = 0xA301
PIC_16F15224 - const word = 0xA302
PIC_16F15225 - const word = 0xA303
PIC_16F15243 - const word = 0xA304
PIC_16F15244 - const word = 0xA305
PIC_16F15245 - const word = 0xA306
PIC_16F15254 - const word = 0xA313
PIC_16F15255 - const word = 0xA314
PIC_16F15256 - const word = 0xA315
PIC_16F1526 - const word = 0x1526
PIC_16F1527 - const word = 0x1527
PIC_16F15274 - const word = 0xA316
PIC_16F15275 - const word = 0xA317
PIC_16F15276 - const word = 0xA318
PIC_16F15313 - const word = 0xA2AE
PIC_16F15323 - const word = 0xA2AF
PIC_16F15324 - const word = 0xA2AA
PIC_16F15325 - const word = 0xA29E
PIC_16F15344 - const word = 0xA2AB
PIC_16F15345 - const word = 0xA29F
PIC_16F15354 - const word = 0xA280
PIC_16F15355 - const word = 0xA27F
PIC_16F15356 - const word = 0xA290
PIC_16F15375 - const word = 0xA292
PIC_16F15376 - const word = 0xA294
PIC_16F15385 - const word = 0xA296
PIC_16F15386 - const word = 0xA298
PIC_16F1574 - const word = 0x1574
PIC_16F1575 - const word = 0x1575
PIC_16F1578 - const word = 0x1578
PIC_16F1579 - const word = 0x1579
PIC_16F1613 - const word = 0x1613
PIC_16F1614 - const word = 0x1614
PIC_16F1615 - const word = 0x1615
PIC_16F1618 - const word = 0x1618
PIC_16F1619 - const word = 0x1619
PIC_16F1703 - const word = 0x1703
PIC_16F1704 - const word = 0x1704
PIC_16F1705 - const word = 0x1705
PIC_16F1707 - const word = 0x1707
PIC_16F1708 - const word = 0x1708
PIC_16F1709 - const word = 0x1709
PIC_16F17114 - const word = 0xA32B
PIC_16F17115 - const word = 0xA32A
PIC_16F17124 - const word = 0xA329
PIC_16F17125 - const word = 0xA328
PIC_16F17126 - const word = 0xA32D
PIC_16F1713 - const word = 0x1713
PIC_16F17144 - const word = 0xA327
PIC_16F17145 - const word = 0xA326
PIC_16F17146 - const word = 0xA32C
PIC_16F17154 - const word = 0xA34F
PIC_16F17155 - const word = 0xA350
PIC_16F17156 - const word = 0xA351
PIC_16F1716 - const word = 0x1716
PIC_16F1717 - const word = 0x1717
PIC_16F17174 - const word = 0xA352
PIC_16F17175 - const word = 0xA353
PIC_16F17176 - const word = 0xA354
PIC_16F1718 - const word = 0x1718
PIC_16F1719 - const word = 0x1719
PIC_16F17524 - const word = 0xA36B
PIC_16F17525 - const word = 0xA36C
PIC_16F17526 - const word = 0xA36D
PIC_16F17544 - const word = 0xA36E
PIC_16F17545 - const word = 0xA36F
PIC_16F17546 - const word = 0xA370
PIC_16F17554 - const word = 0xA371
PIC_16F17555 - const word = 0xA372
PIC_16F17556 - const word = 0xA373
PIC_16F17574 - const word = 0xA374
PIC_16F17575 - const word = 0xA375
PIC_16F17576 - const word = 0xA376
PIC_16F1764 - const word = 0x1764
PIC_16F1765 - const word = 0x1765
PIC_16F1768 - const word = 0x1768
PIC_16F1769 - const word = 0x1769
PIC_16F1773 - const word = 0x1773
PIC_16F1776 - const word = 0x1776
PIC_16F1777 - const word = 0x1777
PIC_16F1778 - const word = 0x1778
PIC_16F1779 - const word = 0x1779
PIC_16F1782 - const word = 0x1782
PIC_16F1783 - const word = 0x1783
PIC_16F1784 - const word = 0x1784
PIC_16F1786 - const word = 0x1786
PIC_16F1787 - const word = 0x1787
PIC_16F1788 - const word = 0x1788
PIC_16F1789 - const word = 0x1789
PIC_16F18013 - const word = 0xA330
PIC_16F18014 - const word = 0xA331
PIC_16F18015 - const word = 0xA332
PIC_16F18023 - const word = 0xA333
PIC_16F18024 - const word = 0xA334
PIC_16F18025 - const word = 0xA335
PIC_16F18026 - const word = 0xA336
PIC_16F18044 - const word = 0xA337
PIC_16F18045 - const word = 0xA338
PIC_16F18046 - const word = 0xA339
PIC_16F18054 - const word = 0xA33A
PIC_16F18055 - const word = 0xA33B
PIC_16F18056 - const word = 0xA32F
PIC_16F18074 - const word = 0xA33C
PIC_16F18075 - const word = 0xA33D
PIC_16F18076 - const word = 0xA32E
PIC_16F18114 - const word = 0xA319
PIC_16F18115 - const word = 0xA31A
PIC_16F18124 - const word = 0xA31B
PIC_16F18125 - const word = 0xA31C
PIC_16F18126 - const word = 0xA31D
PIC_16F18144 - const word = 0xA31E
PIC_16F18145 - const word = 0xA31F
PIC_16F18146 - const word = 0xA323
PIC_16F18154 - const word = 0xA355
PIC_16F18155 - const word = 0xA356
PIC_16F18156 - const word = 0xA357
PIC_16F18174 - const word = 0xA358
PIC_16F18175 - const word = 0xA359
PIC_16F18176 - const word = 0xA35A
PIC_16F1823 - const word = 0x1823
PIC_16F1824 - const word = 0x1824
PIC_16F1825 - const word = 0x1825
PIC_16F1826 - const word = 0x1826
PIC_16F1827 - const word = 0x1827
PIC_16F1828 - const word = 0x1828
PIC_16F1829 - const word = 0x1829
PIC_16F1829LIN - const word = 0xB829
PIC_16F18313 - const word = 0x1832
PIC_16F18323 - const word = 0x1833
PIC_16F18324 - const word = 0x8324
PIC_16F18325 - const word = 0x1835
PIC_16F18326 - const word = 0x8326
PIC_16F18344 - const word = 0x8344
PIC_16F18345 - const word = 0x1834
PIC_16F18346 - const word = 0x8346
PIC_16F18424 - const word = 0xA2DB
PIC_16F18425 - const word = 0xA2DD
PIC_16F18426 - const word = 0xA2D6
PIC_16F18444 - const word = 0xA2DF
PIC_16F18445 - const word = 0xA2E1
PIC_16F18446 - const word = 0xA2D8
PIC_16F18455 - const word = 0xA2E3
PIC_16F18456 - const word = 0xA2E4
PIC_16F1847 - const word = 0x1847
PIC_16F18854 - const word = 0x8854
PIC_16F18855 - const word = 0x8855
PIC_16F18856 - const word = 0x8856
PIC_16F18857 - const word = 0x8857
PIC_16F18875 - const word = 0x8875
PIC_16F18876 - const word = 0x8876
PIC_16F18877 - const word = 0x8877
PIC_16F19155 - const word = 0xA2B2
PIC_16F19156 - const word = 0xA2B3
PIC_16F19175 - const word = 0xA2B4
PIC_16F19176 - const word = 0xA2B5
PIC_16F19185 - const word = 0xA2B6
PIC_16F19186 - const word = 0xA2B7
PIC_16F19195 - const word = 0xA279
PIC_16F19196 - const word = 0xA27A
PIC_16F19197 - const word = 0xA27B
PIC_16F1933 - const word = 0x1933
PIC_16F1934 - const word = 0x1934
PIC_16F1936 - const word = 0x1936
PIC_16F1937 - const word = 0x1937
PIC_16F1938 - const word = 0x1938
PIC_16F1939 - const word = 0x1939
PIC_16F1946 - const word = 0x1946
PIC_16F1947 - const word = 0x1947
PIC_16F505 - const word = 0xF505
PIC_16F506 - const word = 0xF506
PIC_16F526 - const word = 0xF526
PIC_16F54 - const word = 0x6F54
PIC_16F57 - const word = 0x6F57
PIC_16F59 - const word = 0x6F59
PIC_16F610 - const word = 0xF610
PIC_16F616 - const word = 0xF616
PIC_16F627 - const word = 0x6627
PIC_16F627A - const word = 0x627A
PIC_16F628 - const word = 0x6628
PIC_16F628A - const word = 0x628A
PIC_16F630 - const word = 0x6630
PIC_16F631 - const word = 0x6631
PIC_16F636 - const word = 0xF636
PIC_16F639 - const word = 0xF639
PIC_16F648A - const word = 0x648A
PIC_16F676 - const word = 0x6676
PIC_16F677 - const word = 0x6677
PIC_16F684 - const word = 0x6684
PIC_16F685 - const word = 0x6685
PIC_16F687 - const word = 0x6687
PIC_16F688 - const word = 0x6688
PIC_16F689 - const word = 0x6689
PIC_16F690 - const word = 0x6690
PIC_16F707 - const word = 0xF707
PIC_16F716 - const word = 0xF716
PIC_16F72 - const word = 0x672F
PIC_16F720 - const word = 0xF720
PIC_16F721 - const word = 0xF721
PIC_16F722 - const word = 0xF722
PIC_16F722A - const word = 0xA722
PIC_16F723 - const word = 0xF723
PIC_16F723A - const word = 0xA723
PIC_16F724 - const word = 0xF724
PIC_16F726 - const word = 0xF726
PIC_16F727 - const word = 0xF727
PIC_16F73 - const word = 0x673F
PIC_16F737 - const word = 0x6737
PIC_16F74 - const word = 0x674F
PIC_16F747 - const word = 0x6747
PIC_16F753 - const word = 0xF753
PIC_16F76 - const word = 0x676F
PIC_16F767 - const word = 0x6767
PIC_16F77 - const word = 0x677F
PIC_16F777 - const word = 0x6777
PIC_16F785 - const word = 0xF785
PIC_16F818 - const word = 0x818F
PIC_16F819 - const word = 0x819F
PIC_16F83 - const word = 0x6C83
PIC_16F84 - const word = 0x684A
PIC_16F84A - const word = 0x6F84
PIC_16F87 - const word = 0x687F
PIC_16F870 - const word = 0x870F
PIC_16F871 - const word = 0x871F
PIC_16F872 - const word = 0x872F
PIC_16F873 - const word = 0x873F
PIC_16F873A - const word = 0x873A
PIC_16F874 - const word = 0x874F
PIC_16F874A - const word = 0x874A
PIC_16F876 - const word = 0x876F
PIC_16F876A - const word = 0x876A
PIC_16F877 - const word = 0x877F
PIC_16F877A - const word = 0x877A
PIC_16F88 - const word = 0x688F
PIC_16F882 - const word = 0x882F
PIC_16F883 - const word = 0x883F
PIC_16F884 - const word = 0x884F
PIC_16F886 - const word = 0x886F
PIC_16F887 - const word = 0x887F
PIC_16F913 - const word = 0xF913
PIC_16F914 - const word = 0xF914
PIC_16F916 - const word = 0xF916
PIC_16F917 - const word = 0xF917
PIC_16F946 - const word = 0xF946
PIC_16HV610 - const word = 0x6610
PIC_16HV616 - const word = 0x6616
PIC_16HV753 - const word = 0x6753
PIC_16HV785 - const word = 0x6785
PIC_16LF1454 - const word = 0xA454
PIC_16LF1455 - const word = 0xA455
PIC_16LF1459 - const word = 0xA459
PIC_16LF1503 - const word = 0xA503
PIC_16LF1507 - const word = 0xA507
PIC_16LF1508 - const word = 0xA508
PIC_16LF1509 - const word = 0xA509
PIC_16LF1512 - const word = 0xA512
PIC_16LF1513 - const word = 0xA513
PIC_16LF1516 - const word = 0xA516
PIC_16LF1517 - const word = 0xA517
PIC_16LF1518 - const word = 0xA518
PIC_16LF1519 - const word = 0xA519
PIC_16LF1526 - const word = 0xA526
PIC_16LF1527 - const word = 0xA527
PIC_16LF15313 - const word = 0xA2B0
PIC_16LF15323 - const word = 0xA2B1
PIC_16LF15324 - const word = 0xA2AC
PIC_16LF15325 - const word = 0xA2A0
PIC_16LF15344 - const word = 0xA2AD
PIC_16LF15345 - const word = 0xA2A1
PIC_16LF15354 - const word = 0xA282
PIC_16LF15355 - const word = 0xA281
PIC_16LF15356 - const word = 0xA291
PIC_16LF15375 - const word = 0xA293
PIC_16LF15376 - const word = 0xA295
PIC_16LF15385 - const word = 0xA297
PIC_16LF15386 - const word = 0xA299
PIC_16LF1554 - const word = 0xA554
PIC_16LF1559 - const word = 0xA559
PIC_16LF1566 - const word = 0xA566
PIC_16LF1567 - const word = 0xA567
PIC_16LF1574 - const word = 0xA574
PIC_16LF1575 - const word = 0xA575
PIC_16LF1578 - const word = 0xA578
PIC_16LF1579 - const word = 0xA579
PIC_16LF1613 - const word = 0xA613
PIC_16LF1614 - const word = 0xA614
PIC_16LF1615 - const word = 0xA615
PIC_16LF1618 - const word = 0xA618
PIC_16LF1619 - const word = 0xA619
PIC_16LF1703 - const word = 0xA703
PIC_16LF1704 - const word = 0xA704
PIC_16LF1705 - const word = 0xA705
PIC_16LF1707 - const word = 0xA707
PIC_16LF1708 - const word = 0xA708
PIC_16LF1709 - const word = 0xA709
PIC_16LF1713 - const word = 0xA713
PIC_16LF1716 - const word = 0xB716
PIC_16LF1717 - const word = 0xA717
PIC_16LF1718 - const word = 0xA718
PIC_16LF1719 - const word = 0xA719
PIC_16LF1764 - const word = 0xA764
PIC_16LF1765 - const word = 0xA765
PIC_16LF1768 - const word = 0xA768
PIC_16LF1769 - const word = 0xA769
PIC_16LF1773 - const word = 0xA773
PIC_16LF1776 - const word = 0xA776
PIC_16LF1777 - const word = 0xA26D
PIC_16LF1778 - const word = 0xA778
PIC_16LF1779 - const word = 0xA779
PIC_16LF1782 - const word = 0xA782
PIC_16LF1783 - const word = 0xA783
PIC_16LF1784 - const word = 0xA784
PIC_16LF1786 - const word = 0xA786
PIC_16LF1787 - const word = 0xA787
PIC_16LF1788 - const word = 0xA788
PIC_16LF1789 - const word = 0xA789
PIC_16LF1823 - const word = 0xA823
PIC_16LF1824 - const word = 0xA824
PIC_16LF1824T39A - const word = 0xC824
PIC_16LF1825 - const word = 0xA825
PIC_16LF1826 - const word = 0xA826
PIC_16LF1827 - const word = 0xA827
PIC_16LF1828 - const word = 0xA828
PIC_16LF1829 - const word = 0xA829
PIC_16LF18313 - const word = 0xA832
PIC_16LF18323 - const word = 0xA833
PIC_16LF18324 - const word = 0xA324
PIC_16LF18325 - const word = 0xA325
PIC_16LF18326 - const word = 0xA274
PIC_16LF18344 - const word = 0xA344
PIC_16LF18345 - const word = 0xA345
PIC_16LF18346 - const word = 0xA275
PIC_16LF18424 - const word = 0xA2DC
PIC_16LF18425 - const word = 0xA2DE
PIC_16LF18426 - const word = 0xA2D7
PIC_16LF18444 - const word = 0xA2E0
PIC_16LF18445 - const word = 0xA2DA
PIC_16LF18446 - const word = 0xA2D9
PIC_16LF18455 - const word = 0xA2E5
PIC_16LF18456 - const word = 0xA2E6
PIC_16LF1847 - const word = 0xA847
PIC_16LF18854 - const word = 0xA854
PIC_16LF18855 - const word = 0xA855
PIC_16LF18856 - const word = 0xA856
PIC_16LF18857 - const word = 0xA857
PIC_16LF18875 - const word = 0xA875
PIC_16LF18876 - const word = 0xA876
PIC_16LF18877 - const word = 0xA877
PIC_16LF1902 - const word = 0xA902
PIC_16LF1903 - const word = 0xA903
PIC_16LF1904 - const word = 0xA904
PIC_16LF1906 - const word = 0xA906
PIC_16LF1907 - const word = 0xA907
PIC_16LF19155 - const word = 0xA2B8
PIC_16LF19156 - const word = 0xA2B9
PIC_16LF19175 - const word = 0xA2BA
PIC_16LF19176 - const word = 0xA2BB
PIC_16LF19185 - const word = 0xA2BC
PIC_16LF19186 - const word = 0xA2BD
PIC_16LF19195 - const word = 0xA27C
PIC_16LF19196 - const word = 0xA27D
PIC_16LF19197 - const word = 0xA27E
PIC_16LF1933 - const word = 0xA933
PIC_16LF1934 - const word = 0xA934
PIC_16LF1936 - const word = 0xA936
PIC_16LF1937 - const word = 0xA937
PIC_16LF1938 - const word = 0xA938
PIC_16LF1939 - const word = 0xA939
PIC_16LF1946 - const word = 0xA946
PIC_16LF1947 - const word = 0xA947
PIC_16LF627 - const word = 0xA627
PIC_16LF627A - const word = 0xC627
PIC_16LF628 - const word = 0xB628
PIC_16LF628A - const word = 0xC628
PIC_16LF648A - const word = 0xC648
PIC_16LF707 - const word = 0xD707
PIC_16LF720 - const word = 0xD720
PIC_16LF721 - const word = 0xD721
PIC_16LF722 - const word = 0xD722
PIC_16LF722A - const word = 0xB722
PIC_16LF723 - const word = 0xD723
PIC_16LF723A - const word = 0xB723
PIC_16LF724 - const word = 0xD724
PIC_16LF726 - const word = 0xD726
PIC_16LF727 - const word = 0xD727
PIC_16LF73 - const word = 0xA2E9
PIC_16LF74 - const word = 0xA674
PIC_16LF747 - const word = 0xA747
PIC_16LF76 - const word = 0xA676
PIC_16LF767 - const word = 0xA767
PIC_16LF77 - const word = 0xA677
PIC_16LF777 - const word = 0xA777
PIC_16LF818 - const word = 0xA818
PIC_16LF819 - const word = 0xA819
PIC_16LF83 - const word = 0xA683
PIC_16LF84 - const word = 0xA684
PIC_16LF84A - const word = 0xA685
PIC_16LF87 - const word = 0xA807
PIC_16LF870 - const word = 0xA870
PIC_16LF871 - const word = 0xA871
PIC_16LF872 - const word = 0xA800
PIC_16LF873 - const word = 0xA873
PIC_16LF873A - const word = 0xA803
PIC_16LF874 - const word = 0xA874
PIC_16LF874A - const word = 0xA804
PIC_16LF876 - const word = 0xA801
PIC_16LF876A - const word = 0xA805
PIC_16LF877 - const word = 0xA802
PIC_16LF877A - const word = 0xA806
PIC_16LF88 - const word = 0xA808
PIC_18F04Q20 - const word = 0xA34E
PIC_18F04Q40 - const word = 0xA312
PIC_18F04Q41 - const word = 0xA307
PIC_18F05Q20 - const word = 0xA34D
PIC_18F05Q40 - const word = 0xA311
PIC_18F05Q41 - const word = 0xA308
PIC_18F06Q20 - const word = 0xA34C
PIC_18F06Q40 - const word = 0xA310
PIC_18F06Q41 - const word = 0xA309
PIC_18F1220 - const word = 0xA122
PIC_18F1230 - const word = 0x1230
PIC_18F1320 - const word = 0xA132
PIC_18F1330 - const word = 0x1330
PIC_18F13K22 - const word = 0xB132
PIC_18F13K50 - const word = 0xA135
PIC_18F14K22 - const word = 0xB142
PIC_18F14K50 - const word = 0xA145
PIC_18F14Q20 - const word = 0xA34B
PIC_18F14Q40 - const word = 0xA30F
PIC_18F14Q41 - const word = 0xA30A
PIC_18F15Q20 - const word = 0xA34A
PIC_18F15Q40 - const word = 0xA30E
PIC_18F15Q41 - const word = 0xA30B
PIC_18F16Q20 - const word = 0xA349
PIC_18F16Q40 - const word = 0xA30D
PIC_18F16Q41 - const word = 0xA30C
PIC_18F2220 - const word = 0xA222
PIC_18F2221 - const word = 0x2221
PIC_18F2320 - const word = 0xA232
PIC_18F2321 - const word = 0x2321
PIC_18F2331 - const word = 0x2331
PIC_18F23K20 - const word = 0xD320
PIC_18F23K22 - const word = 0xD322
PIC_18F2410 - const word = 0x2410
PIC_18F242 - const word = 0x242F
PIC_18F2420 - const word = 0x2420
PIC_18F2423 - const word = 0x2423
PIC_18F2431 - const word = 0x2431
PIC_18F2439 - const word = 0x2439
PIC_18F2450 - const word = 0x2450
PIC_18F2455 - const word = 0x2455
PIC_18F2458 - const word = 0x2458
PIC_18F248 - const word = 0x8248
PIC_18F2480 - const word = 0x2480
PIC_18F24J10 - const word = 0xD410
PIC_18F24J11 - const word = 0xD411
PIC_18F24J50 - const word = 0xD450
PIC_18F24K20 - const word = 0xD420
PIC_18F24K22 - const word = 0xD422
PIC_18F24K40 - const word = 0x2440
PIC_18F24K42 - const word = 0xA29A
PIC_18F24K50 - const word = 0xD451
PIC_18F24Q10 - const word = 0xA2A6
PIC_18F24Q24 - const word = 0xA361
PIC_18F24Q71 - const word = 0xA348
PIC_18F2510 - const word = 0x2510
PIC_18F2515 - const word = 0x2515
PIC_18F252 - const word = 0x252F
PIC_18F2520 - const word = 0x2520
PIC_18F2523 - const word = 0x2523
PIC_18F2525 - const word = 0x2525
PIC_18F2539 - const word = 0x2539
PIC_18F2550 - const word = 0x2550
PIC_18F2553 - const word = 0x2553
PIC_18F258 - const word = 0x8258
PIC_18F2580 - const word = 0x2580
PIC_18F2585 - const word = 0x2585
PIC_18F25J10 - const word = 0xD510
PIC_18F25J11 - const word = 0xD511
PIC_18F25J50 - const word = 0xD550
PIC_18F25K20 - const word = 0xD520
PIC_18F25K22 - const word = 0xD522
PIC_18F25K40 - const word = 0x2540
PIC_18F25K42 - const word = 0xA29B
PIC_18F25K50 - const word = 0xD551
PIC_18F25K80 - const word = 0xA580
PIC_18F25K83 - const word = 0xA2C8
PIC_18F25Q10 - const word = 0xA2A8
PIC_18F25Q24 - const word = 0xA360
PIC_18F25Q43 - const word = 0xA2FE
PIC_18F25Q71 - const word = 0xA347
PIC_18F2610 - const word = 0x2610
PIC_18F2620 - const word = 0x2620
PIC_18F2680 - const word = 0x2680
PIC_18F2682 - const word = 0x2682
PIC_18F2685 - const word = 0x2685
PIC_18F26J11 - const word = 0xD611
PIC_18F26J13 - const word = 0xD616
PIC_18F26J50 - const word = 0xD650
PIC_18F26J53 - const word = 0xD655
PIC_18F26K20 - const word = 0xD620
PIC_18F26K22 - const word = 0xD622
PIC_18F26K40 - const word = 0x2640
PIC_18F26K42 - const word = 0xA2BE
PIC_18F26K80 - const word = 0xA680
PIC_18F26K83 - const word = 0xA2C9
PIC_18F26Q10 - const word = 0xA2D2
PIC_18F26Q24 - const word = 0xA35D
PIC_18F26Q43 - const word = 0xA2FD
PIC_18F26Q71 - const word = 0xA346
PIC_18F26Q83 - const word = 0xA2ED
PIC_18F26Q84 - const word = 0xA2EE
PIC_18F27J13 - const word = 0xD711
PIC_18F27J53 - const word = 0xD750
PIC_18F27K40 - const word = 0x2740
PIC_18F27K42 - const word = 0xA2CB
PIC_18F27Q10 - const word = 0xA2E7
PIC_18F27Q43 - const word = 0xA2EA
PIC_18F27Q83 - const word = 0xA2EF
PIC_18F27Q84 - const word = 0xA2F0
PIC_18F4220 - const word = 0xA422
PIC_18F4221 - const word = 0x4221
PIC_18F4320 - const word = 0xA432
PIC_18F4321 - const word = 0x4321
PIC_18F4331 - const word = 0x4331
PIC_18F43K20 - const word = 0xE320
PIC_18F43K22 - const word = 0xE322
PIC_18F4410 - const word = 0x4410
PIC_18F442 - const word = 0x442F
PIC_18F4420 - const word = 0x4420
PIC_18F4423 - const word = 0x4423
PIC_18F4431 - const word = 0x4431
PIC_18F4439 - const word = 0x4439
PIC_18F4450 - const word = 0x4450
PIC_18F4455 - const word = 0x4455
PIC_18F4458 - const word = 0x4458
PIC_18F448 - const word = 0x8448
PIC_18F4480 - const word = 0x4480
PIC_18F44J10 - const word = 0xE410
PIC_18F44J11 - const word = 0xE411
PIC_18F44J50 - const word = 0xE450
PIC_18F44K20 - const word = 0xE420
PIC_18F44K22 - const word = 0xE422
PIC_18F44Q71 - const word = 0xA343
PIC_18F4510 - const word = 0x4510
PIC_18F4515 - const word = 0x4515
PIC_18F452 - const word = 0x452F
PIC_18F4520 - const word = 0x4520
PIC_18F4523 - const word = 0x4523
PIC_18F4525 - const word = 0x4525
PIC_18F4539 - const word = 0x4539
PIC_18F4550 - const word = 0x4550
PIC_18F4553 - const word = 0x4553
PIC_18F458 - const word = 0x8458
PIC_18F4580 - const word = 0x4580
PIC_18F4585 - const word = 0x4585
PIC_18F45J10 - const word = 0xE510
PIC_18F45J11 - const word = 0xE511
PIC_18F45J50 - const word = 0xE550
PIC_18F45K20 - const word = 0xE520
PIC_18F45K22 - const word = 0xE522
PIC_18F45K40 - const word = 0x4540
PIC_18F45K42 - const word = 0xA2C0
PIC_18F45K50 - const word = 0xE551
PIC_18F45K80 - const word = 0xB580
PIC_18F45Q10 - const word = 0xA2D3
PIC_18F45Q24 - const word = 0xA35F
PIC_18F45Q43 - const word = 0xA2FC
PIC_18F45Q71 - const word = 0xA342
PIC_18F4610 - const word = 0x4610
PIC_18F4620 - const word = 0x4620
PIC_18F4680 - const word = 0x4680
PIC_18F4682 - const word = 0x4682
PIC_18F4685 - const word = 0x4685
PIC_18F46J11 - const word = 0xE611
PIC_18F46J13 - const word = 0xE616
PIC_18F46J50 - const word = 0xE650
PIC_18F46J53 - const word = 0xE655
PIC_18F46K20 - const word = 0xE620
PIC_18F46K22 - const word = 0xE622
PIC_18F46K40 - const word = 0x4640
PIC_18F46K42 - const word = 0xA2C4
PIC_18F46K80 - const word = 0xB680
PIC_18F46Q10 - const word = 0xA2D4
PIC_18F46Q24 - const word = 0xA35C
PIC_18F46Q43 - const word = 0xA2FB
PIC_18F46Q71 - const word = 0xA341
PIC_18F46Q83 - const word = 0xA2F1
PIC_18F46Q84 - const word = 0xA2F2
PIC_18F47J13 - const word = 0xE711
PIC_18F47J53 - const word = 0xE750
PIC_18F47K40 - const word = 0x4740
PIC_18F47K42 - const word = 0xA2CD
PIC_18F47Q10 - const word = 0xA2E8
PIC_18F47Q43 - const word = 0xA2EB
PIC_18F47Q83 - const word = 0xA2F3
PIC_18F47Q84 - const word = 0xA2F4
PIC_18F54Q71 - const word = 0xA340
PIC_18F55K42 - const word = 0xA2C2
PIC_18F55Q24 - const word = 0xA35E
PIC_18F55Q43 - const word = 0xA2FA
PIC_18F55Q71 - const word = 0xA33F
PIC_18F56K42 - const word = 0xA2C6
PIC_18F56Q24 - const word = 0xA35B
PIC_18F56Q43 - const word = 0xA2F9
PIC_18F56Q71 - const word = 0xA33E
PIC_18F56Q83 - const word = 0xA2F5
PIC_18F56Q84 - const word = 0xA2F6
PIC_18F57K42 - const word = 0xA2CF
PIC_18F57Q43 - const word = 0xA2EC
PIC_18F57Q83 - const word = 0xA2F7
PIC_18F57Q84 - const word = 0xA2F8
PIC_18F6310 - const word = 0x6310
PIC_18F6390 - const word = 0x6390
PIC_18F6393 - const word = 0x6393
PIC_18F63J11 - const word = 0x6311
PIC_18F63J90 - const word = 0xB390
PIC_18F6410 - const word = 0x6410
PIC_18F6490 - const word = 0x6490
PIC_18F6493 - const word = 0x6493
PIC_18F64J11 - const word = 0x6411
PIC_18F64J90 - const word = 0xB490
PIC_18F6520 - const word = 0xA652
PIC_18F6525 - const word = 0x6525
PIC_18F6527 - const word = 0x6527
PIC_18F6585 - const word = 0x6585
PIC_18F65J10 - const word = 0xB510
PIC_18F65J11 - const word = 0x6511
PIC_18F65J15 - const word = 0xB515
PIC_18F65J50 - const word = 0xB550
PIC_18F65J90 - const word = 0xB590
PIC_18F65J94 - const word = 0x6594
PIC_18F65K22 - const word = 0x6522
PIC_18F65K40 - const word = 0xA26F
PIC_18F65K80 - const word = 0xC580
PIC_18F65K90 - const word = 0xB591
PIC_18F6620 - const word = 0xA662
PIC_18F6621 - const word = 0xA621
PIC_18F6622 - const word = 0xF622
PIC_18F6627 - const word = 0xF625
PIC_18F6628 - const word = 0xA628
PIC_18F6680 - const word = 0x6680
PIC_18F66J10 - const word = 0xB610
PIC_18F66J11 - const word = 0xB611
PIC_18F66J15 - const word = 0xB615
PIC_18F66J16 - const word = 0xB616
PIC_18F66J50 - const word = 0xB650
PIC_18F66J55 - const word = 0xB655
PIC_18F66J60 - const word = 0xB660
PIC_18F66J65 - const word = 0xB665
PIC_18F66J90 - const word = 0xB690
PIC_18F66J93 - const word = 0x6693
PIC_18F66J94 - const word = 0x6694
PIC_18F66J99 - const word = 0x6699
PIC_18F66K22 - const word = 0xB622
PIC_18F66K40 - const word = 0x6640
PIC_18F66K80 - const word = 0xC680
PIC_18F66K90 - const word = 0xB691
PIC_18F6720 - const word = 0xA672
PIC_18F6722 - const word = 0x6721
PIC_18F6723 - const word = 0x6723
PIC_18F67J10 - const word = 0xB710
PIC_18F67J11 - const word = 0xB711
PIC_18F67J50 - const word = 0xB750
PIC_18F67J60 - const word = 0xB760
PIC_18F67J90 - const word = 0x6790
PIC_18F67J93 - const word = 0x6793
PIC_18F67J94 - const word = 0x6794
PIC_18F67K22 - const word = 0x6722
PIC_18F67K40 - const word = 0x6740
PIC_18F67K90 - const word = 0xB790
PIC_18F8310 - const word = 0x8310
PIC_18F8390 - const word = 0x8390
PIC_18F8393 - const word = 0x8393
PIC_18F83J11 - const word = 0x8311
PIC_18F83J90 - const word = 0xC390
PIC_18F8410 - const word = 0x8410
PIC_18F8490 - const word = 0x8490
PIC_18F8493 - const word = 0x8493
PIC_18F84J11 - const word = 0x8411
PIC_18F84J90 - const word = 0xC490
PIC_18F8520 - const word = 0xA852
PIC_18F8525 - const word = 0x8525
PIC_18F8527 - const word = 0x8527
PIC_18F8585 - const word = 0x8585
PIC_18F85J10 - const word = 0xC510
PIC_18F85J11 - const word = 0x8511
PIC_18F85J15 - const word = 0xC515
PIC_18F85J50 - const word = 0xC550
PIC_18F85J90 - const word = 0xC590
PIC_18F85J94 - const word = 0x8594
PIC_18F85K22 - const word = 0x8522
PIC_18F85K90 - const word = 0xC591
PIC_18F8620 - const word = 0xA862
PIC_18F8621 - const word = 0x8621
PIC_18F8622 - const word = 0x8622
PIC_18F8627 - const word = 0x8625
PIC_18F8628 - const word = 0x8628
PIC_18F8680 - const word = 0x8680
PIC_18F86J10 - const word = 0xC610
PIC_18F86J11 - const word = 0xC611
PIC_18F86J15 - const word = 0xC615
PIC_18F86J16 - const word = 0xC616
PIC_18F86J50 - const word = 0xC650
PIC_18F86J55 - const word = 0xC655
PIC_18F86J60 - const word = 0xC660
PIC_18F86J65 - const word = 0xC665
PIC_18F86J72 - const word = 0x8672
PIC_18F86J90 - const word = 0x8690
PIC_18F86J93 - const word = 0x8693
PIC_18F86J94 - const word = 0x8694
PIC_18F86J99 - const word = 0x8699
PIC_18F86K22 - const word = 0xC622
PIC_18F86K90 - const word = 0xC690
PIC_18F8720 - const word = 0xA872
PIC_18F8722 - const word = 0x8721
PIC_18F8723 - const word = 0x8723
PIC_18F87J10 - const word = 0xC710
PIC_18F87J11 - const word = 0xC711
PIC_18F87J50 - const word = 0xC750
PIC_18F87J60 - const word = 0xC760
PIC_18F87J72 - const word = 0x8772
PIC_18F87J90 - const word = 0x8790
PIC_18F87J93 - const word = 0x8793
PIC_18F87J94 - const word = 0x8794
PIC_18F87K22 - const word = 0x8722
PIC_18F87K90 - const word = 0xC790
PIC_18F95J94 - const word = 0x9594
PIC_18F96J60 - const word = 0xD660
PIC_18F96J65 - const word = 0xD665
PIC_18F96J94 - const word = 0x9694
PIC_18F96J99 - const word = 0x9699
PIC_18F97J60 - const word = 0xD760
PIC_18F97J94 - const word = 0x9794
PIC_18LF1220 - const word = 0xA120
PIC_18LF1230 - const word = 0xA121
PIC_18LF1320 - const word = 0xA130
PIC_18LF1330 - const word = 0xA131
PIC_18LF13K22 - const word = 0xA133
PIC_18LF13K50 - const word = 0xD135
PIC_18LF14K22 - const word = 0xA142
PIC_18LF14K50 - const word = 0xD145
PIC_18LF2220 - const word = 0xA200
PIC_18LF2221 - const word = 0xA201
PIC_18LF2320 - const word = 0xA202
PIC_18LF2321 - const word = 0xA203
PIC_18LF2331 - const word = 0xA204
PIC_18LF23K22 - const word = 0xB322
PIC_18LF2410 - const word = 0xA205
PIC_18LF242 - const word = 0xA208
PIC_18LF2420 - const word = 0xA206
PIC_18LF2423 - const word = 0xA207
PIC_18LF2431 - const word = 0xA209
PIC_18LF2439 - const word = 0xA210
PIC_18LF2450 - const word = 0xA20A
PIC_18LF2455 - const word = 0xA20B
PIC_18LF2458 - const word = 0xA20C
PIC_18LF248 - const word = 0xA20E
PIC_18LF2480 - const word = 0xA20D
PIC_18LF24J10 - const word = 0xA241
PIC_18LF24J11 - const word = 0xB411
PIC_18LF24J50 - const word = 0xB450
PIC_18LF24K22 - const word = 0xB422
PIC_18LF24K40 - const word = 0xC244
PIC_18LF24K42 - const word = 0xA29C
PIC_18LF24K50 - const word = 0xD452
PIC_18LF2510 - const word = 0xA20F
PIC_18LF2515 - const word = 0xA211
PIC_18LF252 - const word = 0xA215
PIC_18LF2520 - const word = 0xA212
PIC_18LF2523 - const word = 0xA213
PIC_18LF2525 - const word = 0xA214
PIC_18LF2539 - const word = 0xA216
PIC_18LF2550 - const word = 0xA217
PIC_18LF2553 - const word = 0xA218
PIC_18LF258 - const word = 0xA21B
PIC_18LF2580 - const word = 0xA219
PIC_18LF2585 - const word = 0xA21A
PIC_18LF25J10 - const word = 0xA251
PIC_18LF25J11 - const word = 0xB511
PIC_18LF25J50 - const word = 0xB551
PIC_18LF25K22 - const word = 0xB522
PIC_18LF25K40 - const word = 0xC254
PIC_18LF25K42 - const word = 0xA29D
PIC_18LF25K50 - const word = 0xD552
PIC_18LF25K80 - const word = 0xD580
PIC_18LF25K83 - const word = 0xA2D1
PIC_18LF2610 - const word = 0xA21C
PIC_18LF2620 - const word = 0xA21D
PIC_18LF2680 - const word = 0xA21E
PIC_18LF2682 - const word = 0xA21F
PIC_18LF2685 - const word = 0xA220
PIC_18LF26J11 - const word = 0xB612
PIC_18LF26J13 - const word = 0xB617
PIC_18LF26J50 - const word = 0xB651
PIC_18LF26J53 - const word = 0xB656
PIC_18LF26K22 - const word = 0xB623
PIC_18LF26K40 - const word = 0xA640
PIC_18LF26K42 - const word = 0xA2BF
PIC_18LF26K80 - const word = 0xD680
PIC_18LF26K83 - const word = 0xA2CA
PIC_18LF27J13 - const word = 0xB712
PIC_18LF27J53 - const word = 0xC753
PIC_18LF27K40 - const word = 0xA277
PIC_18LF27K42 - const word = 0xA2CC
PIC_18LF4220 - const word = 0xA223
PIC_18LF4221 - const word = 0xA224
PIC_18LF4320 - const word = 0xA225
PIC_18LF4321 - const word = 0xA226
PIC_18LF4331 - const word = 0xA227
PIC_18LF43K22 - const word = 0xC322
PIC_18LF4410 - const word = 0xA228
PIC_18LF442 - const word = 0xA22A
PIC_18LF4420 - const word = 0xA229
PIC_18LF4423 - const word = 0xA22B
PIC_18LF4431 - const word = 0xA22C
PIC_18LF4439 - const word = 0xA22D
PIC_18LF4450 - const word = 0xA22E
PIC_18LF4455 - const word = 0xA22F
PIC_18LF4458 - const word = 0xA230
PIC_18LF448 - const word = 0xA233
PIC_18LF4480 - const word = 0xA231
PIC_18LF44J10 - const word = 0xA441
PIC_18LF44J11 - const word = 0xC411
PIC_18LF44J50 - const word = 0xC450
PIC_18LF44K22 - const word = 0xC422
PIC_18LF4510 - const word = 0xA234
PIC_18LF4515 - const word = 0xA235
PIC_18LF452 - const word = 0xA236
PIC_18LF4520 - const word = 0xA237
PIC_18LF4523 - const word = 0xA238
PIC_18LF4525 - const word = 0xA239
PIC_18LF4539 - const word = 0xA23A
PIC_18LF4550 - const word = 0xA23B
PIC_18LF4553 - const word = 0xA23C
PIC_18LF458 - const word = 0xA23F
PIC_18LF4580 - const word = 0xA23D
PIC_18LF4585 - const word = 0xA23E
PIC_18LF45J10 - const word = 0xA451
PIC_18LF45J11 - const word = 0xC511
PIC_18LF45J50 - const word = 0xC551
PIC_18LF45K22 - const word = 0xC522
PIC_18LF45K40 - const word = 0xC454
PIC_18LF45K42 - const word = 0xA2C1
PIC_18LF45K50 - const word = 0xE552
PIC_18LF45K80 - const word = 0xE580
PIC_18LF4610 - const word = 0xA240
PIC_18LF4620 - const word = 0xA242
PIC_18LF4680 - const word = 0xA243
PIC_18LF4682 - const word = 0xA244
PIC_18LF4685 - const word = 0xA245
PIC_18LF46J11 - const word = 0xC612
PIC_18LF46J13 - const word = 0xC617
PIC_18LF46J50 - const word = 0xC651
PIC_18LF46J53 - const word = 0xC656
PIC_18LF46K22 - const word = 0xC623
PIC_18LF46K40 - const word = 0xA26E
PIC_18LF46K42 - const word = 0xA2C5
PIC_18LF46K80 - const word = 0xE680
PIC_18LF47J13 - const word = 0xC712
PIC_18LF47J53 - const word = 0xC751
PIC_18LF47K40 - const word = 0xA276
PIC_18LF47K42 - const word = 0xA2CE
PIC_18LF55K42 - const word = 0xA2C3
PIC_18LF56K42 - const word = 0xA2C7
PIC_18LF57K42 - const word = 0xA2D0
PIC_18LF6310 - const word = 0xA246
PIC_18LF6390 - const word = 0xA247
PIC_18LF6393 - const word = 0xA248
PIC_18LF6410 - const word = 0xA249
PIC_18LF6490 - const word = 0xA24A
PIC_18LF6493 - const word = 0xA24B
PIC_18LF6520 - const word = 0xA24C
PIC_18LF6525 - const word = 0xA24D
PIC_18LF6527 - const word = 0xA24E
PIC_18LF6585 - const word = 0xA24F
PIC_18LF65K40 - const word = 0xA270
PIC_18LF65K80 - const word = 0xF580
PIC_18LF6620 - const word = 0xA250
PIC_18LF6621 - const word = 0xA252
PIC_18LF6622 - const word = 0xA253
PIC_18LF6627 - const word = 0xA254
PIC_18LF6628 - const word = 0xA255
PIC_18LF6680 - const word = 0xA256
PIC_18LF66K40 - const word = 0xA271
PIC_18LF66K80 - const word = 0xF680
PIC_18LF6720 - const word = 0xA257
PIC_18LF6722 - const word = 0xA258
PIC_18LF6723 - const word = 0xA259
PIC_18LF67K40 - const word = 0xA278
PIC_18LF8310 - const word = 0xA25A
PIC_18LF8390 - const word = 0xA25B
PIC_18LF8393 - const word = 0xA25C
PIC_18LF8410 - const word = 0xA25D
PIC_18LF8490 - const word = 0xA25E
PIC_18LF8493 - const word = 0xA25F
PIC_18LF8520 - const word = 0xA260
PIC_18LF8525 - const word = 0xA261
PIC_18LF8527 - const word = 0xA262
PIC_18LF8585 - const word = 0xA263
PIC_18LF8620 - const word = 0xA264
PIC_18LF8621 - const word = 0xA265
PIC_18LF8622 - const word = 0xA266
PIC_18LF8627 - const word = 0xA267
PIC_18LF8628 - const word = 0xA268
PIC_18LF8680 - const word = 0xA269
PIC_18LF8720 - const word = 0xA26A
PIC_18LF8722 - const word = 0xA26B
PIC_18LF8723 - const word = 0xA26C


clear_rtc_alarm_1_flag - JALlib Procedures Help

clear_rtc_alarm_1_flag JALLIB PROCEDURE

Signature

procedure clear_rtc_alarm_1_flag() is

Description

Clears alarm flag 1.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


clear_rtc_alarm_2_flag - JALlib Procedures Help

clear_rtc_alarm_2_flag JALLIB PROCEDURE

Signature

procedure clear_rtc_alarm_2_flag() is

Description

Clears alarm flag 2.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


co2_t6603.jal - JALLIB Library Documentation

co2_t6603.jal JALLIB LIBRARY

Title

T6603_CO2, read values from GE/Telaire T6603 CO2 sensor.

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, Adapted-by: Albert Faber

Compiler

=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library communicates with the T6603 GE/Telaire CO2 sensor.
This sensor uses the Telaire Tsunami-Lite Commnications Protocol
available functions are:
get_status() return byte
get_co2_ppm() return word -- CO2 concentration in ppm
get_serial_numer() return string[15]
get_elevation_m() return word -- in meters above sea level
This library uses the serial_hardware and delay libraries.
These libs must be included and initialised in the main program before
including this one. This code is published with approval from GE.

Sources

http://www.ge-mcs.com/download/sensing-manuals/T63182-003.pdf
if this document moves, google for: http://www.google.com/search?q=telaire+tsnuami+lite
Some clippings from the protocol document:
-------------- START OF PROTOCOL DOCUMENT CLIPPINGS ---------------------
The UART communications interface expects a frame size of 8 bits, no parity,
one stop bit, and a baud rate of 19200.
A communications delay of several seconds occurs when the Sensor is powered
up or power cycled. This communications delay time is necessary for the
sensor to initialize and achieve full functionality.
UART Commands from PC to Sensor
Commands sent from a host to the Sensor have the following format:
<flag><address><length><command><additional_data>
where:
<flag> the hex value 0xFF
<address> one byte hex value. The byte 0xFE is an addr that sensors respond.
<length> total length in bytes of the command and additional data
<command> one byte hex command, values explained below
<add_data> may or may not be applicable, depending upon the command
For example, to request Sensor identification, the following command is used:
0x FF 0xFE 0x02 0x02 0x03
<flag> <addr> <length> <command> = CMD_READ <additional data> = CO2_PPM
The length of the command is 0x02, since the command CMD_READ, CO2_PPM
consists of the two bytes 0x02 0x01.
UART Response from Sensor to PC
Responses returned from the Sensor to the host have the following format:
<flag><address><length><response_data>
<flag> the hex value 0xFF.
<address> one byte hex value. The byte 0xFA signifies to master
<length> total length in bytes of the response data
<resp_data> may or may not be applicable, depending upon the command
In response to the above identification command CMD_READ CO2_PPM, one Sensor
replied with the following byte stream:
0xFF 0xFA 0x02 0x01 0xD5
<flag> <address> <lenght> <resp_data>
The length of the response_data is 2 bytes (0x02). The response is 0x01D5, -- so 469 ppm, a normal value in a city.
UART Acknowledgement or <ACK> Reply
Some commands require that a Sensor only confirm that the command was
received and the appropriate action was taken. In this case, when a Sensor
does not need to return data in response to a command, it will instead reply
with an Acknowledgement response, called an <ACK>.
This is a response packet formatted as shown above, but with the <length>
equal to 0x00, and no response data present:
0xFF 0xFA 0x00
<flag> <address> <length>
-------------- END OF PROTOCOL DOCUMENT CLIPPINGS -----------------------

Routines

  • get_co2_elevation_m - Function returns word
  • get_co2_ppm - Function returns word
  • get_co2_serial_number - Procedure
  • get_co2_status - Function returns byte
  • set_co2_elevation_m - Procedure


co2_t6613_i2c.jal - JALLIB Library Documentation

co2_t6613_i2c.jal JALLIB LIBRARY

Title

co2_t6613_i2c, read values from GE/Telaire T6613 CO2 sensor.

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2013

Compiler

=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library communicates with the T6613 GE/Telaire CO2 sensor,
via I2C. The protocol doc isn't on the web: email eur@fiwihex.nl to get it.
available functions are:
get_status() return byte
get_co2_ppm() return word -- CO2 concentration in ppm
get_serial_numer() return string[15]
get_elevation_m() return word -- in meters above sea level
---------
declare in your main program, before including this library:
const word _i2c_bus_speed = 1 -- * 100kHz
const bit _i2c_level = true
include i2c_hardware -- there is software i2c too
i2c_initialize()
var bit tx_ok -- check if all transmissions went OK
-----------

Notes

sensor pinout, top view: (gold box visible)
A B C 2 4 6 8 10 12
1 3 5 7 9 11
where:
A TX (UART)
B RX (UART)
C V+ (5V DC)
1 +5V
2 GND
3 GND
4 AV OUT (0..4V DC)
5 SCL (I2C)
6 NC
7 SDA (I2C)
8 NC
9 NC
10 TX (UART)
11 RX (UART)
12 GND
for this library, you need only connect pins 1, 3, 5 & 7
----------------
Memory map:
T66xx memory map
addr Description lt wgt RW/RO write read description write description
0x00 Elevation 2 msb RW W: 0 xx xx xx xx elevation in hex
0x01 lsb
0x02 Span PPM 2 msb RW W: 2 xx xx xx xx span in hex T6615 only
0x03 lb
0x04 sngl p trgt 2 msb RW W: 4 xx xx xx xx single point in hex
0x05 lsb
0x06 zero cal cmd 1 RW W: 6 0F 00: flags set
0x07 span cal cmd 1 RW W: 7 0F 00: flags set T6615 only
0x08 sngl pnt cal cmd 1 RW W: 8 0F 00: flags set
0x09 ABC logic enable 1 RW W: 9 0x 01:ABC on, 02:ABC off 01:on, 02:off, 03:reset and on
0x0A Sensor idle cmd 1 RW W: A 0x 00 after cmd 01:idle on, 02:idle off
0x0B Reset cmd 1 RW W: B 0F 00 after cmd
0x0C span2 cal cmd 1 RW W: C 0F 00: flags set T6615 only
0x0D span2 ppm 2 RW W: D xx xx
0x20 CO2 reading 2 msb RO
0x21 lsb
0x22 status byte RO 00:normal, 1x: error, 02:warmup, 04:calibration, 08:idle
0x23 reserved
0x24 reserved
0x25 reserved
0x26 reserved
0x27 serial 16 array[0] RO
0x28 array[1]
[..] [..]
0x36 array[15]

Constants and Variables

t6613_addr - const byte = 0b0001_0000 -- 0x08 in 7-bit notation
0x08 in 7-bit notation

Routines

  • get_co2_elevation_m - Function returns word
  • get_co2_ppm - Function returns word
  • get_co2_serial_number - Procedure
  • get_co2_status - Function returns byte
  • reset_t6613 - Procedure
  • set_co2_elevation_m - Procedure


co_encode_cob_id - JALlib Procedures Help

co_encode_cob_id JALLIB PROCEDURE

Signature

procedure co_encode_cob_id(byte in func, byte in node_id, dword out cob_id) is

Description

format the COB-ID, which is a 'standard' 11-bit CAN identifier.
the function code is upper 4 bits, the node_id is lower 7 bits.

Include

To use this procedure, include the library:

include canopen

Parameters

  • func - byte in
  • node_id - byte in
  • cob_id - dword out

Return Value

None

Example

From sample file: 16f819_canopen_mcp2515_txhb.jal

-- Title: TX test of CANopen library and external can_mpc2515 controller
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4m
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Sends a CANopen 'Heartbeat' twice a second and blinks LED
--
-- This file has been generated by hand (manually maintained)
--
-- Note:  uses SPI Master library and also needs a 'chip select' pin such as:
--              var bit can_sel is pin_B0
--

include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

enable_digital_io()

var bit led is pin_A0
pin_A0_direction = output

var bit can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515
include canopen

for 3 loop
   led = on
   delay_100ms(2)
   led = off
   delay_100ms(2)
end loop

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)
can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)
can_write(CANCTRL, 0x07) -- Normal mode
delay_100ms(1)

-- build the CANopen "COB-ID" for Heartbeat message
const byte NODE_ID = 1  -- valid nodes: 1-127
const byte HB_FUNC = 0x0E
var dword cob_id
co_encode_cob_id(HB_FUNC, NODE_ID, cob_id)

forever loop
   var byte hb_state
   var byte txdata[8] -- for this test, we only use 1 byte of 8 possible.

   -- mimic changing our node's 'state'.
   -- this is just for testing.
   if hb_state == 4 then
      hb_state = 5
   else
      hb_state = 4
   end if
   txdata[0] = hb_state

   -- send the CANopen heartbeat message
   co_send(cob_id, txdata, 1)

   led = led ^ 1
   delay_100ms(5)
end loop

Generated by JALlib CHM Help System | Source: canopen.jal


co_send - JALlib Procedures Help

co_send JALLIB PROCEDURE

Signature

procedure co_send(dword in cob_id, byte in data[8], byte in len) is

Description

send standard 11-bit CANopen message
FIXME: we are only using one of the TX buffers (3 are available)
FIXME: handle timeout

Include

To use this procedure, include the library:

include canopen

Parameters

  • cob_id - dword in
  • data[] - byte in
  • len - byte in

Return Value

None

Example

From sample file: 16f819_canopen_mcp2515_txhb.jal

-- Title: TX test of CANopen library and external can_mpc2515 controller
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4m
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Sends a CANopen 'Heartbeat' twice a second and blinks LED
--
-- This file has been generated by hand (manually maintained)
--
-- Note:  uses SPI Master library and also needs a 'chip select' pin such as:
--              var bit can_sel is pin_B0
--

include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

enable_digital_io()

var bit led is pin_A0
pin_A0_direction = output

var bit can_sel is pin_B0
pin_B0_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include can_mcp2515
include canopen

for 3 loop
   led = on
   delay_100ms(2)
   led = off
   delay_100ms(2)
end loop

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)
can_reset()
delay_100ms(1)

-- 125K bps
can_set_config(0x01, 0x89, 0x82)
can_write(CAN_TXB0CTRL, 0)
can_write(CAN_TXB1CTRL, 0)
can_write(CAN_TXB2CTRL, 0)
can_write(CANCTRL, 0x07) -- Normal mode
delay_100ms(1)

-- build the CANopen "COB-ID" for Heartbeat message
const byte NODE_ID = 1  -- valid nodes: 1-127
const byte HB_FUNC = 0x0E
var dword cob_id
co_encode_cob_id(HB_FUNC, NODE_ID, cob_id)

forever loop
   var byte hb_state
   var byte txdata[8] -- for this test, we only use 1 byte of 8 possible.

   -- mimic changing our node's 'state'.
   -- this is just for testing.
   if hb_state == 4 then
      hb_state = 5
   else
      hb_state = 4
   end if
   txdata[0] = hb_state

   -- send the CANopen heartbeat message
   co_send(cob_id, txdata, 1)

   led = led ^ 1
   delay_100ms(5)
end loop

Generated by JALlib CHM Help System | Source: canopen.jal


Common Macros - JAL Language Syntax Reference

Common Macros JALV2 SYNTAX

Description

Generated by JAL Syntax Documentation System | Source: DITA


constants_jallib.jal - JALLIB Library Documentation

constants_jallib.jal JALLIB LIBRARY

Title

Common include file for Jallib libraries

Author

Rob Hamerling, Copyright (c) 2010..2024, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Common include file for Jallib libraries

Notes

---------------------------------------------------

------------------------------------------------------------------------------
Commonly used general purpose constants
------------------------------------------------------------------------------

Constants and Variables

TRUE - const bit = 1
FALSE - const bit = 0
HIGH - const bit = TRUE
LOW - const bit = FALSE
ON - const bit = TRUE
OFF - const bit = FALSE
ENABLED - const bit = TRUE
DISABLED - const bit = FALSE
INPUT - const bit = TRUE
OUTPUT - const bit = FALSE
ALL_INPUT - const byte = 0b_1111_1111
ALL_OUTPUT - const byte = 0b_0000_0000
ALL_ENABLED - const byte = 0b_1111_1111
ALL_DISABLED - const byte = 0b_0000_0000
ADC_NO_EXT_VREF - const byte = 0 -- defaults to Vdd
defaults to Vdd
ADC_VREF_POS - const byte = 1
ADC_VREF_POS_NEG - const byte = 2
ADC_VREF_NEG - const byte = 3
ADC_VREF_FVR - const byte = 4
STOPWATCH_NS - const byte = 1
STOPWATCH_US - const byte = 2
STOPWATCH_MS - const byte = 3
STOPWATCH_S - const byte = 4
CRC_ERROR_SUCCESS - const byte = 0
CRC_ERROR_INVALID_PARAMETER - const byte = 1
CRC_ERROR_NOT_READY - const byte = 2


COUNT - JAL Language Syntax Reference

COUNT JALV2 SYNTAX

Syntax

COUNT(array_identifier)

Description

Returns number of array elements. Result type UNIVERSAL.

Notes

Useful for array iteration without hardcoding size.

Example

VAR BYTE data[10]
size = COUNT(data)  -- size = 10

Generated by JAL Syntax Documentation System | Source: DITA


crc7_calculate_array_bytes - JALlib Procedures Help

crc7_calculate_array_bytes JALLIB FUNCTION

Signature

function crc7_calculate_array_bytes(byte in data[], word in length) return byte is

Description

Calculate CRC7 for byte array (one-shot calculation)
Parameters: data[] - array of bytes to process, length - number of bytes
Returns: calculated CRC7 value
Processes entire array in one operation

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

  • data[] - byte in
  • length - word in

Return Value

byte - calculated CRC7 value Processes entire array in one operation

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_calculate_bytes - JALlib Procedures Help

crc7_calculate_bytes JALLIB PROCEDURE

Signature

procedure crc7_calculate_bytes(byte in data) is

Description

Calculate CRC7 for a single byte (incremental processing)
Parameters: data - single byte to process
Updates internal CRC state with new data byte

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_calculate_large_array_bytes - JALlib Procedures Help

crc7_calculate_large_array_bytes JALLIB FUNCTION

Signature

function crc7_calculate_large_array_bytes(word in length) return byte is

Description

Calculate CRC7 for large array (bytes)
Parameters: length - number of bytes to process from large_array_4
Returns: calculated CRC7 value
Processes bytes from large_array_4 alias

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

  • length - word in

Return Value

byte - calculated CRC7 value Processes bytes from large_array_4 alias

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_get_result - JALlib Procedures Help

crc7_get_result JALLIB FUNCTION

Signature

function crc7_get_result() return byte is

Description

Get final CRC7 result
Returns: calculated CRC7 value
Marks calculation as complete and returns the final CRC result

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

None

Return Value

byte - calculated CRC7 value Marks calculation as complete and returns the final CRC result

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_is_complete - JALlib Procedures Help

crc7_is_complete JALLIB FUNCTION

Signature

function crc7_is_complete() return bit is

Description

Check if CRC7 calculation is complete
Returns: TRUE if calculation is complete, FALSE otherwise
Indicates whether the CRC calculation has been finalized

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

None

Return Value

bit - TRUE if calculation is complete, FALSE otherwise Indicates whether the CRC calculation has been finalized

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_sd_card.jal - JALLIB Library Documentation

crc7_sd_card.jal JALLIB LIBRARY

Title

Library for communicating with SD memory cards

Author

Matthew Schinkel, copyright (c) 2009..2022, all rights reserved.

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides functions for SD memory cards.

Notes

SD card SPI mode is 1,1
This version works with standard capacity sd cards up to 4gb and
high capacity up to 32 gb. Extended Capacity up to 2TB
may be supported later on.

Sources

SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
http://www.rjhcoding.com/avrc-sd-interface-3.php

Constants and Variables

CRC7_POLYNOMIAL - const byte = 0x89

Routines

  • crc7_calculate_array_bytes - Function returns byte
  • crc7_calculate_bytes - Procedure
  • crc7_calculate_large_array_bytes - Function returns byte
  • crc7_calculate_large_array_dwords - Function returns byte
  • crc7_calculate_large_array_words - Function returns byte
  • crc7_get_error_type - Function returns byte
  • crc7_get_result - Function returns byte
  • crc7_has_error - Function returns bit
  • crc7_is_complete - Function returns bit
  • crc7_reset - Procedure
  • crc7_start - Procedure
  • crc7_verify - Function returns bit
  • crc7_verify_data - Function returns bit
  • crc7_verify_large_array - Function returns bit
  • crc7_verify_large_array_dwords - Function returns bit
  • crc7_verify_large_array_words - Function returns bit


crc7_start - JALlib Procedures Help

crc7_start JALLIB PROCEDURE

Signature

procedure crc7_start(word in expected_bytes) is

Description

Start CRC7 calculation with expected byte count
Parameters: expected_bytes - total number of bytes to be processed
Initializes CRC calculation state and sets up for incremental processing

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

  • expected_bytes - word in

Return Value

None

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_verify_data - JALlib Procedures Help

crc7_verify_data JALLIB FUNCTION

Signature

function crc7_verify_data(byte in data[], word in length, byte in expected) return bit is

Description

Verify CRC7 for data array
Parameters: data[] - array to verify, length - number of bytes, expected - expected CRC
Returns: TRUE if calculated CRC matches expected, FALSE otherwise
Calculates CRC for array and compares with expected value

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

  • data[] - byte in
  • length - word in
  • expected - byte in

Return Value

bit - TRUE if calculated CRC matches expected, FALSE otherwise Calculates CRC for array and compares with expected value

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc7_verify_large_array - JALlib Procedures Help

crc7_verify_large_array JALLIB FUNCTION

Signature

function crc7_verify_large_array(word in length, byte in expected) return bit is

Description

Verify CRC7 for large array (bytes)
Parameters: length - number of bytes to verify, expected - expected CRC
Returns: TRUE if calculated CRC matches expected, FALSE otherwise
Calculates CRC for bytes from large_array_4 and compares with expected value

Include

To use this procedure, include the library:

include crc7_sd_card

Parameters

  • length - word in
  • expected - byte in

Return Value

bit - TRUE if calculated CRC matches expected, FALSE otherwise Calculates CRC for bytes from large_array_4 and compares with expected value

Example

From sample file: 18f67j50_crc7_bitwise.jal

-- Title: CRC7-SD Card Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC7-SD Card bitwise implementation library usage.
-- This sample uses the bitwise algorithm for SD Card CRC7 calculations.
--
-- CRC7-SD Card Implementation Details:
-- Polynomial: 0x89 (x⁷ + x³ + 1) - SD Card specific
-- Initial Value: 0x00
-- Expected CRC Value: 0xB5 (verified by hardware)
-- Status: SD Card CRC7 implementation
-- Note: This uses polynomial 0x89 as per SD Card specification
--
-- Standard CRC7 Reference (for comparison):
-- Polynomial: 0x89 (x⁷ + x³ + 1)
-- Initial Value: 0x00
-- Test Data: ASCII "123456789" = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39]
-- Expected CRC Value: 0x75
-- Sources: CRC RevEng Catalogue, SD Card specification
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz - 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- intext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital IO
_usec_delay (100_000) -- wait for power to stabilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const dword LARGE_ARRAY_6_SIZE = 512
const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1
include large_array_6
alias crc_large_array_bytes is large_array_6

const dword LARGE_ARRAY_5_SIZE = 512
const dword LARGE_ARRAY_5_VARIABLE_SIZE = 2
include large_array_5
alias crc_large_array_word is large_array_5

const dword LARGE_ARRAY_4_SIZE = 512
const dword LARGE_ARRAY_4_VARIABLE_SIZE = 4
include large_array_4
alias crc_large_array_dword is large_array_4

include crc7_sd_card

const byte test_data[] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}
const word test_data_length = 10

var byte crc7_value
var word i

procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data, sample_started)
print_crlf(serial_data)
seperator()
print_string(serial_data, "CRC7-BITWISE DEMONSTRATION")
print_crlf(serial_data)
seperator()

-- Test 1: Incremental
print_string(serial_data, "Test 1: CRC7 Incremental Calculation")
print_crlf(serial_data)
print_string(serial_data, "Processing ")
print_word_dec(serial_data, test_data_length)
print_string(serial_data, " bytes...")
print_crlf(serial_data)
crc7_start(test_data_length)
for test_data_length using i loop
   crc7_calculate_bytes(test_data[i])
end loop
if crc7_is_complete() then
   crc7_value = crc7_get_result()
   print_string(serial_data, "CRC7 Result: 0x")
   print_byte_hex(serial_data, crc7_value)
   print_crlf(serial_data)
end if
seperator()

-- Test 2: Array one-shot
print_string(serial_data, "Test 2: Array-based CRC Calculation")
print_crlf(serial_data)
crc7_value = crc7_calculate_array_bytes(test_data, test_data_length)
print_string(serial_data, "CRC7 Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 3: Large array (bytes)
print_string(serial_data, "Test 3: Large Array CRC Calculation")
print_crlf(serial_data)
for test_data_length using i loop
   crc_large_array_bytes[i] = test_data[i]
end loop
crc7_value = crc7_calculate_large_array_bytes(test_data_length)
print_string(serial_data, "CRC7 Large Array Result: 0x")
print_byte_hex(serial_data, crc7_value)
print_crlf(serial_data)
seperator()

-- Test 4: Verify helpers
print_string(serial_data, "Test 4: Result Validation")
print_crlf(serial_data)
const byte expected_crc7 = 0xB5
if crc7_verify_data(test_data, test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Auto-Verify: PASS")
else
   print_string(serial_data, "CRC7 Auto-Verify: FAIL")
end if
print_crlf(serial_data)
if crc7_verify_large_array(test_data_length, expected_crc7) then
   print_string(serial_data, "CRC7 Large Array Verify: PASS")
else
   print_string(serial_data, "CRC7 Large Array Verify: FAIL")
end if
print_crlf(serial_data)
seperator()

print_string(serial_data, "=== CRC7-BITWISE SAMPLE COMPLETE ===")
print_crlf(serial_data)
print_string(serial_data, "##DONE##")
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc7_sd_card.jal


crc16_calculate_array_bytes - JALlib Procedures Help

crc16_calculate_array_bytes JALLIB FUNCTION

Signature

function crc16_calculate_array_bytes(byte in data[], word in length) return word is

Description

Calculate CRC16 for a byte array (one-shot calculation)
Parameters: data[] - array of bytes to process, length - number of bytes
Returns: calculated CRC16 value
Processes entire array in one operation

Include

To use this procedure, include the library:

include crc16_ccitt_bitwise

Parameters

  • data[] - byte in
  • length - word in

Return Value

word - calculated CRC16 value Processes entire array in one operation

Example

From sample file: 18f67j50_crc16_ccitt_bitwise.jal

-- Title: CRC16-CCITT Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT bitwise implementation library usage.
-- This sample uses the bitwise algorithm implementation for CRC16-CCITT calculations.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Bitwise implementation - slower than lookup table but uses less memory
-- Use Case: When memory is limited or when you need the reference implementation
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions
include crc16_ccitt_bitwise

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- Hardware serial configuration
const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- Test data
const byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Variables
var word calculated_crc
var byte i

-- Main program

-- Debug: Sample starting
var byte startup_msg[] = "DEBUG: Sample starting..."
print_string(serial_data, startup_msg)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with standard implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
    print_byte_hex(serial_data, test_data[j])
    print_string(serial_data, " ")
end loop
print_crlf(serial_data)

-- Debug: Show expected CRC
var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

calculated_crc = crc16_calculate_array_bytes(test_data, 4)

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
    var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
    print_string(serial_data, pass_msg)
else
    var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
    print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before incremental calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_start(4)

-- Debug: Show each byte being processed
for 4 using i loop
    var byte debug6_msg[] = "DEBUG: Processing byte "
    print_string(serial_data, debug6_msg)
    print_byte_hex(serial_data, test_data[i])
    print_crlf(serial_data)
    crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After incremental calculation
var byte debug7_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug7_msg)
print_crlf(serial_data)

var byte calc2_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc2_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
    var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
    print_string(serial_data, pass2_msg)
else
    var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
    print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_verify(calculated_crc, expected_crc)
if crc16_error_occurred() then
    var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
    print_string(serial_data, fail3_msg)
else
    var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
    print_string(serial_data, pass3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

var byte complete_msg[] = "***CRC16-CCITT Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)

var byte done_msg[] = "##DONE##"
print_string(serial_data, done_msg)
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_bitwise.jal


crc16_calculate_bytes - JALlib Procedures Help

crc16_calculate_bytes JALLIB PROCEDURE

Signature

procedure crc16_calculate_bytes(byte in data) is

Description

Calculate CRC16 for a single byte using bitwise algorithm
Parameters: data - single byte to process
Updates internal CRC state with new data byte using bitwise algorithm

Include

To use this procedure, include the library:

include crc16_ccitt_bitwise

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f67j50_crc16_ccitt_lookup.jal

-- Title: CRC16-CCITT Lookup Table Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT lookup table implementation library usage.
-- This sample uses the lookup table algorithm implementation for maximum CRC calculation speed.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Lookup table implementation - faster than bitwise but uses more memory
-- Memory Layout: 4 separate 64-entry tables to work around 8-bit PIC memory limitations
-- Use Case: When speed is critical and memory is available for lookup tables
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- Include the lookup table library
include crc16_ccitt_lookup

-- Test data
var byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

crc16_init(4)
crc16_calculate_bytes(test_data[0])
crc16_calculate_bytes(test_data[1])
crc16_calculate_bytes(test_data[2])
crc16_calculate_bytes(test_data[3])

var word calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
   print_string(serial_data, pass_msg)
else
   var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
   print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_init(4)
var byte i
for 4 using i loop
   var byte debug_byte_msg[] = "DEBUG: Processing byte "
   print_string(serial_data, debug_byte_msg)
   print_byte_hex(serial_data, test_data[i])
   print_crlf(serial_data)
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug6_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug6_msg)
print_crlf(serial_data)

print_string(serial_data, "Calculated CRC16: 0x")
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
   print_string(serial_data, pass2_msg)
else
   var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
   print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_init(4)
for 4 using i loop
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

if crc16_verify(calculated_crc, expected_crc) then
   var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
   print_string(serial_data, pass3_msg)
else
   var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
   print_string(serial_data, fail3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Lookup Table Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with lookup table implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
   print_byte_hex(serial_data, test_data[j])
   print_string(serial_data, " ")
end loop
print_crlf(serial_data)

var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)
print_crlf(serial_data)

-- Print completion message
var byte complete_msg[] = "***CRC16-CCITT Lookup Table Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)
print_crlf(serial_data)

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_bitwise.jal


crc16_ccitt_bitwise.jal - JALLIB Library Documentation

crc16_ccitt_bitwise.jal JALLIB LIBRARY

Title

CRC16-CCITT Bitwise Implementation Library

Author

Matthew Schinkel

Compiler

>=2.4r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

CRC16-CCITT implementation using optimized bitwise algorithm.
Provides incremental and one-shot calculation over bytes using direct bit manipulation.
This is the reference implementation for CRC16-CCITT with polynomial 0x1021.
CRC16-CCITT Implementation Details:
Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
Initial Value: 0x0000
Final XOR: 0x0000 (none)
Input Reflection: No
Output Reflection: No
Performance: Optimized bitwise implementation - slower than lookup table but uses less memory
Program must provide large array aliases when using large-array helpers:
alias crc_large_array_bytes is large_array_4
alias crc_large_array_word is large_array_5
alias crc_large_array_dword is large_array_6

Constants and Variables

CRC16_POLYNOMIAL - const word = 0x1021

Routines

  • crc16_calculate_array_bytes - Function returns word
  • crc16_calculate_bytes - Procedure
  • crc16_error_occurred - Function returns bit
  • crc16_get_error_type - Function returns byte
  • crc16_get_result - Function returns word
  • crc16_is_complete - Function returns bit
  • crc16_start - Procedure
  • crc16_verify - Procedure


crc16_ccitt_lookup.jal - JALLIB Library Documentation

crc16_ccitt_lookup.jal JALLIB LIBRARY

Title

CRC16-CCITT Lookup Table Implementation Library

Author

Matthew Schinkel

Compiler

>=2.4r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

CRC16-CCITT implementation using lookup table for maximum speed.
This version splits the large table into smaller chunks to avoid 8-bit PIC memory issues.
Provides identical results to the bitwise implementation but with better performance.
CRC16-CCITT Implementation Details:
Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
Initial Value: 0x0000
Final XOR: 0x0000 (none)
Input Reflection: No
Output Reflection: No
Performance: Lookup table implementation - faster than bitwise but uses more memory
Memory Layout: 4 separate 64-entry tables (CRC16_TABLE_0 through CRC16_TABLE_3)
Compatibility: Full compatibility with bitwise implementation - identical results
Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
Expected CRC Value: 0xD789 (verified by JAL sample)

CRC16-CCITT constants

Constants and Variables

CRC16_POLYNOMIAL - const word = 0x1021

Routines

  • crc16_calculate_bytes - Procedure
  • crc16_get_error_type - Function returns byte
  • crc16_get_result - Function returns word
  • crc16_get_table_value - Function returns word
  • crc16_has_error - Function returns bit
  • crc16_init - Procedure
  • crc16_is_complete - Function returns bit
  • crc16_verify - Function returns bit


crc16_error_occurred - JALlib Procedures Help

crc16_error_occurred JALLIB FUNCTION

Signature

function crc16_error_occurred() return bit is

Description

Check if error occurred
Returns: TRUE if error occurred, FALSE otherwise
Indicates whether an error was detected during CRC calculation

Include

To use this procedure, include the library:

include crc16_ccitt_bitwise

Parameters

None

Return Value

bit - TRUE if error occurred, FALSE otherwise Indicates whether an error was detected during CRC calculation

Example

From sample file: 18f67j50_crc16_ccitt_bitwise.jal

-- Title: CRC16-CCITT Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT bitwise implementation library usage.
-- This sample uses the bitwise algorithm implementation for CRC16-CCITT calculations.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Bitwise implementation - slower than lookup table but uses less memory
-- Use Case: When memory is limited or when you need the reference implementation
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions
include crc16_ccitt_bitwise

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- Hardware serial configuration
const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- Test data
const byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Variables
var word calculated_crc
var byte i

-- Main program

-- Debug: Sample starting
var byte startup_msg[] = "DEBUG: Sample starting..."
print_string(serial_data, startup_msg)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with standard implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
    print_byte_hex(serial_data, test_data[j])
    print_string(serial_data, " ")
end loop
print_crlf(serial_data)

-- Debug: Show expected CRC
var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

calculated_crc = crc16_calculate_array_bytes(test_data, 4)

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
    var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
    print_string(serial_data, pass_msg)
else
    var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
    print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before incremental calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_start(4)

-- Debug: Show each byte being processed
for 4 using i loop
    var byte debug6_msg[] = "DEBUG: Processing byte "
    print_string(serial_data, debug6_msg)
    print_byte_hex(serial_data, test_data[i])
    print_crlf(serial_data)
    crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After incremental calculation
var byte debug7_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug7_msg)
print_crlf(serial_data)

var byte calc2_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc2_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
    var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
    print_string(serial_data, pass2_msg)
else
    var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
    print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_verify(calculated_crc, expected_crc)
if crc16_error_occurred() then
    var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
    print_string(serial_data, fail3_msg)
else
    var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
    print_string(serial_data, pass3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

var byte complete_msg[] = "***CRC16-CCITT Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)

var byte done_msg[] = "##DONE##"
print_string(serial_data, done_msg)
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_bitwise.jal


crc16_get_result - JALlib Procedures Help

crc16_get_result JALLIB FUNCTION

Signature

function crc16_get_result() return word is

Description

Get CRC16 result
Returns: calculated CRC16 value
Returns the current CRC16 value (intermediate or final)

Include

To use this procedure, include the library:

include crc16_ccitt_bitwise

Parameters

None

Return Value

word - calculated CRC16 value Returns the current CRC16 value (intermediate or final)

Example

From sample file: 18f67j50_crc16_ccitt_lookup.jal

-- Title: CRC16-CCITT Lookup Table Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT lookup table implementation library usage.
-- This sample uses the lookup table algorithm implementation for maximum CRC calculation speed.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Lookup table implementation - faster than bitwise but uses more memory
-- Memory Layout: 4 separate 64-entry tables to work around 8-bit PIC memory limitations
-- Use Case: When speed is critical and memory is available for lookup tables
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- Include the lookup table library
include crc16_ccitt_lookup

-- Test data
var byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

crc16_init(4)
crc16_calculate_bytes(test_data[0])
crc16_calculate_bytes(test_data[1])
crc16_calculate_bytes(test_data[2])
crc16_calculate_bytes(test_data[3])

var word calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
   print_string(serial_data, pass_msg)
else
   var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
   print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_init(4)
var byte i
for 4 using i loop
   var byte debug_byte_msg[] = "DEBUG: Processing byte "
   print_string(serial_data, debug_byte_msg)
   print_byte_hex(serial_data, test_data[i])
   print_crlf(serial_data)
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug6_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug6_msg)
print_crlf(serial_data)

print_string(serial_data, "Calculated CRC16: 0x")
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
   print_string(serial_data, pass2_msg)
else
   var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
   print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_init(4)
for 4 using i loop
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

if crc16_verify(calculated_crc, expected_crc) then
   var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
   print_string(serial_data, pass3_msg)
else
   var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
   print_string(serial_data, fail3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Lookup Table Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with lookup table implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
   print_byte_hex(serial_data, test_data[j])
   print_string(serial_data, " ")
end loop
print_crlf(serial_data)

var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)
print_crlf(serial_data)

-- Print completion message
var byte complete_msg[] = "***CRC16-CCITT Lookup Table Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)
print_crlf(serial_data)

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_bitwise.jal


crc16_init - JALlib Procedures Help

crc16_init JALLIB PROCEDURE

Signature

procedure crc16_init(byte in total_bytes) is

Description

Initialize CRC16 calculation
Parameters: total_bytes - expected number of bytes to process
Initializes CRC calculation state and sets up for incremental processing

Include

To use this procedure, include the library:

include crc16_ccitt_lookup

Parameters

  • total_bytes - byte in

Return Value

None

Example

From sample file: 18f67j50_crc16_ccitt_lookup.jal

-- Title: CRC16-CCITT Lookup Table Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT lookup table implementation library usage.
-- This sample uses the lookup table algorithm implementation for maximum CRC calculation speed.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Lookup table implementation - faster than bitwise but uses more memory
-- Memory Layout: 4 separate 64-entry tables to work around 8-bit PIC memory limitations
-- Use Case: When speed is critical and memory is available for lookup tables
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- Include the lookup table library
include crc16_ccitt_lookup

-- Test data
var byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

crc16_init(4)
crc16_calculate_bytes(test_data[0])
crc16_calculate_bytes(test_data[1])
crc16_calculate_bytes(test_data[2])
crc16_calculate_bytes(test_data[3])

var word calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
   print_string(serial_data, pass_msg)
else
   var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
   print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_init(4)
var byte i
for 4 using i loop
   var byte debug_byte_msg[] = "DEBUG: Processing byte "
   print_string(serial_data, debug_byte_msg)
   print_byte_hex(serial_data, test_data[i])
   print_crlf(serial_data)
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug6_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug6_msg)
print_crlf(serial_data)

print_string(serial_data, "Calculated CRC16: 0x")
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
   print_string(serial_data, pass2_msg)
else
   var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
   print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_init(4)
for 4 using i loop
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

if crc16_verify(calculated_crc, expected_crc) then
   var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
   print_string(serial_data, pass3_msg)
else
   var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
   print_string(serial_data, fail3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Lookup Table Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with lookup table implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
   print_byte_hex(serial_data, test_data[j])
   print_string(serial_data, " ")
end loop
print_crlf(serial_data)

var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)
print_crlf(serial_data)

-- Print completion message
var byte complete_msg[] = "***CRC16-CCITT Lookup Table Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)
print_crlf(serial_data)

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_lookup.jal


crc16_start - JALlib Procedures Help

crc16_start JALLIB PROCEDURE

Signature

procedure crc16_start(word in expected_bytes) is

Description

Initialize CRC16 calculation
Parameters: expected_bytes - expected number of bytes to process
Initializes CRC calculation state and sets up for incremental processing

Include

To use this procedure, include the library:

include crc16_ccitt_bitwise

Parameters

  • expected_bytes - word in

Return Value

None

Example

From sample file: 18f67j50_crc16_ccitt_bitwise.jal

-- Title: CRC16-CCITT Bitwise Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT bitwise implementation library usage.
-- This sample uses the bitwise algorithm implementation for CRC16-CCITT calculations.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Bitwise implementation - slower than lookup table but uses less memory
-- Use Case: When memory is limited or when you need the reference implementation
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions
include crc16_ccitt_bitwise

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- Hardware serial configuration
const serial_hw_baudrate  = 9600
include serial_hardware
serial_hw_init()
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- Test data
const byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Variables
var word calculated_crc
var byte i

-- Main program

-- Debug: Sample starting
var byte startup_msg[] = "DEBUG: Sample starting..."
print_string(serial_data, startup_msg)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with standard implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
    print_byte_hex(serial_data, test_data[j])
    print_string(serial_data, " ")
end loop
print_crlf(serial_data)

-- Debug: Show expected CRC
var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

calculated_crc = crc16_calculate_array_bytes(test_data, 4)

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
    var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
    print_string(serial_data, pass_msg)
else
    var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
    print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before incremental calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_start(4)

-- Debug: Show each byte being processed
for 4 using i loop
    var byte debug6_msg[] = "DEBUG: Processing byte "
    print_string(serial_data, debug6_msg)
    print_byte_hex(serial_data, test_data[i])
    print_crlf(serial_data)
    crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After incremental calculation
var byte debug7_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug7_msg)
print_crlf(serial_data)

var byte calc2_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc2_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
    var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
    print_string(serial_data, pass2_msg)
else
    var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
    print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_verify(calculated_crc, expected_crc)
if crc16_error_occurred() then
    var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
    print_string(serial_data, fail3_msg)
else
    var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
    print_string(serial_data, pass3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

var byte complete_msg[] = "***CRC16-CCITT Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)

var byte done_msg[] = "##DONE##"
print_string(serial_data, done_msg)
print_crlf(serial_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_bitwise.jal


crc16_verify - JALlib Procedures Help

crc16_verify JALLIB PROCEDURE

Signature

procedure crc16_verify(word in calculated, word in expected) is

Description

Verify CRC16 result
Parameters: calculated - computed CRC value, expected - expected CRC value
Compares calculated CRC against expected value for validation

Include

To use this procedure, include the library:

include crc16_ccitt_bitwise

Parameters

  • calculated - word in
  • expected - word in

Return Value

None

Example

From sample file: 18f67j50_crc16_ccitt_lookup.jal

-- Title: CRC16-CCITT Lookup Table Implementation Sample
-- Author: Matthew Schinkel
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates CRC16-CCITT lookup table implementation library usage.
-- This sample uses the lookup table algorithm implementation for maximum CRC calculation speed.
--
-- CRC16-CCITT Implementation Details:
-- Polynomial: 0x1021 (x¹⁶ + x¹² + x⁵ + 1)
-- Initial Value: 0x0000
-- Final XOR: 0x0000 (none)
-- Test Data: "1234" = [0x31, 0x32, 0x33, 0x34]
-- Expected CRC Value: 0xD789 (verified by JAL sample)
--
-- Performance: Lookup table implementation - faster than bitwise but uses more memory
-- Memory Layout: 4 separate 64-entry tables to work around 8-bit PIC memory limitations
-- Use Case: When speed is critical and memory is available for lookup tables
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

--
include delay                        -- delay functions

-- Print library
const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- Include the lookup table library
include crc16_ccitt_lookup

-- Test data
var byte test_data[4] = {0x31, 0x32, 0x33, 0x34}  -- "1234"
const word expected_crc = 0xD789

-- Test 1: Array calculation
var byte test1_msg[] = "Test 1: Array calculation"
print_string(serial_data, test1_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug3_msg[] = "DEBUG: Starting array calculation..."
print_string(serial_data, debug3_msg)
print_crlf(serial_data)

crc16_init(4)
crc16_calculate_bytes(test_data[0])
crc16_calculate_bytes(test_data[1])
crc16_calculate_bytes(test_data[2])
crc16_calculate_bytes(test_data[3])

var word calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug4_msg[] = "DEBUG: Array calculation complete"
print_string(serial_data, debug4_msg)
print_crlf(serial_data)

var byte calc_msg[] = "Calculated CRC16: 0x"
print_string(serial_data, calc_msg)
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

var byte exp_msg[] = "Expected CRC16: 0x"
print_string(serial_data, exp_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass_msg[] = "Test 1 PASSED - CRC matches expected value"
   print_string(serial_data, pass_msg)
else
   var byte fail_msg[] = "Test 1 FAILED - CRC does not match expected value"
   print_string(serial_data, fail_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 2: Incremental calculation
var byte test2_msg[] = "Test 2: Incremental calculation"
print_string(serial_data, test2_msg)
print_crlf(serial_data)

-- Debug: Before calculation
var byte debug5_msg[] = "DEBUG: Starting incremental calculation..."
print_string(serial_data, debug5_msg)
print_crlf(serial_data)

crc16_init(4)
var byte i
for 4 using i loop
   var byte debug_byte_msg[] = "DEBUG: Processing byte "
   print_string(serial_data, debug_byte_msg)
   print_byte_hex(serial_data, test_data[i])
   print_crlf(serial_data)
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

-- Debug: After calculation
var byte debug6_msg[] = "DEBUG: Incremental calculation complete"
print_string(serial_data, debug6_msg)
print_crlf(serial_data)

print_string(serial_data, "Calculated CRC16: 0x")
print_word_hex(serial_data, calculated_crc)
print_crlf(serial_data)

if calculated_crc == expected_crc then
   var byte pass2_msg[] = "Test 2 PASSED - Incremental CRC matches expected value"
   print_string(serial_data, pass2_msg)
else
   var byte fail2_msg[] = "Test 2 FAILED - Incremental CRC does not match expected value"
   print_string(serial_data, fail2_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Test 3: Verify function
var byte test3_msg[] = "Test 3: Verify function"
print_string(serial_data, test3_msg)
print_crlf(serial_data)

crc16_init(4)
for 4 using i loop
   crc16_calculate_bytes(test_data[i])
end loop

calculated_crc = crc16_get_result()

if crc16_verify(calculated_crc, expected_crc) then
   var byte pass3_msg[] = "Test 3 PASSED - Verify function works correctly"
   print_string(serial_data, pass3_msg)
else
   var byte fail3_msg[] = "Test 3 FAILED - Verify function detected error"
   print_string(serial_data, fail3_msg)
end if
print_crlf(serial_data)
print_crlf(serial_data)

-- Print header
var byte header_msg[] = "***CRC16-CCITT Lookup Table Sample Started***"
print_string(serial_data, header_msg)
print_crlf(serial_data)

var byte test_msg[] = "Testing CRC16-CCITT with lookup table implementation..."
print_string(serial_data, test_msg)
print_crlf(serial_data)
print_crlf(serial_data)

-- Debug: Show test data
var byte debug1_msg[] = "DEBUG: Test data = "
print_string(serial_data, debug1_msg)
var byte j
for 4 using j loop
   print_byte_hex(serial_data, test_data[j])
   print_string(serial_data, " ")
end loop
print_crlf(serial_data)

var byte debug2_msg[] = "DEBUG: Expected CRC = 0x"
print_string(serial_data, debug2_msg)
print_word_hex(serial_data, expected_crc)
print_crlf(serial_data)
print_crlf(serial_data)

-- Print completion message
var byte complete_msg[] = "***CRC16-CCITT Lookup Table Sample Complete***"
print_string(serial_data, complete_msg)
print_crlf(serial_data)
print_crlf(serial_data)

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: crc16_ccitt_bitwise.jal


crc_clear_error - JALlib Procedures Help

crc_clear_error JALLIB PROCEDURE

Signature

procedure crc_clear_error() is

Description

Clear CRC error flags
Resets CRC error state for retry operations

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


crc_init - JALlib Procedures Help

crc_init JALLIB PROCEDURE

Signature

procedure crc_init() is

Description

Initialize CRC calculation system
Prepares CRC libraries for SD card operations

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


d1w_init - JALlib Procedures Help

d1w_init JALLIB PROCEDURE

Signature

procedure d1w_init() is

Description

No description available.

Include

To use this procedure, include the library:

include one_wire

Parameters

None

Return Value

None

Example

From sample file: 16f648a_ds18b20_single.jal

-- ------------------------------------------------------
-- Title: Test program for ds18b20.jal
--
-- Author: Vasile Guta Ciucur, Copyright (c) 2010..2014, all rights reserved.
--
-- Adapted-by: mkerna@gmail.com, Joep Suijs
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--    Read sensor temperature DS18B20 from a specific device using the
--    drive's ID
--
-- Sources:
--
-- Notes: requires LCD to display result
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_ds18b20_single.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b4              -- LCD command/data select.
alias lcd_rs_direction is pin_b4_direction
alias lcd_en           is pin_b0              -- LCD data trigger
alias lcd_en_direction is pin_b0_direction

alias lcd_dataport is porta_low              -- LCD data  port
alias lcd_dataport_direction is porta_low_direction
const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line

include delay
include print
include format
enable_digital_io()  -- set all IO as digital

-- setup lcd
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include lcd_hd44780_4                -- LCD library with 4 data lines
lcd_init()                           -- initialize LCD
alias device is lcd

-- ----------------------------
-- start of setup ds18b20 stuff
-- ----------------------------

-- setup pin definitions for dallas one-wire bus
alias d1w_bus            is pin_b1
alias d1w_bus_direction  is pin_b1_direction
include one_wire           -- include one-wire library
d1w_init()                 -- init one-wire bus

-- select one of the output formats below
const ds18b20_value_raw          = 0
const ds18b20_value_celcius      = 1
const ds18b20_value_farenheit    = 0

const ds18b20_ignore_crc         = 0 -- 1 tell lib to ignore crc (code becomes smaller and faster, but reliability of data is less)
const ds18b20_max_retries        = 2 -- 1 means the library re-reads once when crc fails, 4 means up to 4 retries (so max 5 reads)

include ds18b20            -- include library for ds18b20 temperature sensor with one-wire interface

-- ---------------------------
-- end of setup ds18b20 stuff
-- ---------------------------

-- strings and vars for the main loop
const byte str1[]       = "Temp="
const byte str_err1[]   = "ds18b20 read failed."
var byte i
var sword temperature
var bit r

forever loop

   ds18b20_convert()  -- tell all ds18b20 devices to start conversion

   -- note: the statement above starts the conversion and it can take
   -- up to 750ms to complete.
   -- If the sensor is in parasite mode, it is mandatory to leave the bus
   -- during conversion. You could include a delay like:
   delay_1ms(750)
   -- If you have other stuff to do, feel free to do so and create proper
   -- timing in an other way.
   --
   -- If the sensor is conventional powered, you don't have to keep the
   -- bus idle and could read the sensor before conversion is complete.
   -- The sensor will return the previous value.

   r = ds18b20_s_temp(temperature)                 -- read conversion result
   lcd_cursor_position(0,0)                        -- first line
   if (r) then
      -- success, so print temperature
      print_string(device, str1)                   -- print string
      format_sword_dec(device, temperature, 4, 1)  -- print temperature in xx.x format
      device = "C"
      device = " "
   else
      -- print fail message
      print_string(device, str_err1)
   end if

   -- read the device's ID and print it
   lcd_cursor_position(1,0)          -- second line

   r = ds18b20_s_read_rom()
   if (r) then
      -- read_rom successful, so print ID which is now stored in scratchpad
      for 8 using i loop
         print_byte_hex(device, scratchpad[i])
      end loop
   else
      -- print fail message
      print_string(device, str_err1)
   end if

end loop

Generated by JALlib CHM Help System | Source: one_wire.jal


dac_mcp4922.jal - JALLIB Library Documentation

dac_mcp4922.jal JALLIB LIBRARY

Title

MCP4922.jal

Author

Peter Lankreijer

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library controls a MCP4922 via the SPI protocol.

Notes

The following should be defined in the main program:
setup SPI for software SPI or none for hardware SPI
include spi_master_sw
define directions
spi_master_sw_init(SPI_MODE_11)
alias spi_master is spi_master_sw
alias spi_master_exchange is spi_master_sw_exchange
alias mcp4922_cs is pin_??
alias MCP4922_CS_direction is output is pin_??_direction
alias LDAC is pin_??
alias LDAC_direction is output is pin_??_direction
The SHDN pin should be connected to high
Todo:
Shutdown DAC_A, DAC_B or both

Define variables

Sources

delay.jal
spi_master_sw.jal or spi_master_hw.jal
http://ww1.microchip.com/downloads/en/DeviceDoc/22250A.pdf
Functions: MCP4922_init(bit in Buffer, bit in Gain, bit in Shutdown)
DAC_A(word in A)
DAC_B(word in B)
DAC_AB(word in A, word in B)

Routines

  • mcp4922_dac - Procedure
  • mcp4922_dac_a - Procedure
  • mcp4922_dac_ab - Procedure
  • mcp4922_dac_b - Procedure
  • mcp4922_init - Procedure
  • mcp4922_split_word - Procedure


Data Directives - JAL Language Syntax Reference

Data Directives JALV2 SYNTAX

Description

The following allow data to be directly inserted into the code area. Retrieving these data is chip-specific. Also, as the data go directly into the program memory, the amount of space actually used is chip specific. Below, the term db dw ds

Generated by JAL Syntax Documentation System | Source: DITA


data_eeprom - JALlib Procedures Help

data_eeprom JALLIB FUNCTION

Signature

function data_eeprom(word in offset) return byte is

Description

Title: Read byte of data EEPROM at given offset
Arguments: Offset in data EEPROM of byte to be read
Returns: Byte of data EEPROM

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in

Return Value

byte - Byte of data EEPROM

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_eeprom_read - JALlib Procedures Help

data_eeprom_read JALLIB PROCEDURE

Signature

procedure data_eeprom_read(word in offset, byte out data) is

Description

Title: Read byte from data EEPROM at given offset
Arguments: - Offset in data EEPROM of byte to be read
- Data (byte) to store data EEPROM contents
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in
  • data - byte out

Return Value

None

Example

From sample file: 16f88_remember_me.jal

-- Title: Sample showing basic read/write operations on data eeprom
-- Author: Sebastien Lelong, Copyright (c) 2008, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4g
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows a basic usage to read from and write to data eeprom.
-- The first time, it asks for your name, complaining it does not know you...
-- Enter your name, then turn off the PIC. Turn on, it still knows you. Amazing !
-- --
-- You can re-enter your name again, by entering "$" (1 dollar sign) to switch to
-- input mode. This is a basic example of how to implement a read/eval/print/loop (REPL)
--
-- This file has been generated by hand (manually maintained)
--
-- Input/Output:
-- [open your favorite serial term]
-- [turn on your PIC, you should have something like...]
-- Hi,
-- (press '$' to enter your name...)
-- [follow instructions]
-- Erasing eeprom... done !
-- I don't know you, please enter your name, then press [RETURN]
-- Sebastien Lelong
-- Hi, Sebastien Lelong
-- (press '$' to enter your name...)
-- [turn off/on PIC, it remembers you !]
-- Hi, Sebastien Lelong
-- (press '$' to enter your name...)

include 16f88
-- set all IO as digital
enable_digital_io()

-- We'll use internal oscillator. It work @ 8MHz
pragma target clock		8_000_000
pragma target OSC		INTOSC_NOCLKOUT
-- Specify no postscaler, ie. really runs @8MHz
OSCCON_IRCF = 0b_111
-- no watchdog, please
pragma target WDT		disabled

-- ok, now setup serial
-- we want to use USART/RS232, not SPI
const usart_hw_serial = true	-- true = RS232, false = SPI
-- setup speed. Standard values are: 57_600, 19_200, 9_600, 2_400, ...
const serial_hw_baudrate = 19_200
-- now we can use serial_hardware module
include serial_hardware
-- initialize the whole with our parameters
serial_hw_init()

include pic_data_eeprom
include print

-- This is where we start reading/writing
-- We could start from 0, but for fun (...),
-- we'll start at 10.
const EEPROM_ADD_START = 10
-- We'll also use a counter to know where we are
var byte eeprom_counter = 0

-- Because we don't want to handle eeprom address logic
-- everywhere in the code, we defines convinient functions
-- and procedures
--
-- store a char, and set next eeprom position
procedure store_char(byte in char) is
    data_eeprom_write(EEPROM_ADD_START + eeprom_counter,char)
    eeprom_counter = eeprom_counter + 1
end procedure

-- read char from eeprom, at current address, then
-- set to next eeprom position
function read_char() return byte is
    var byte char
    data_eeprom_read(EEPROM_ADD_START + eeprom_counter,char)
    eeprom_counter = eeprom_counter + 1
    return char
end function

procedure reset() is
    eeprom_counter = byte(EEPROM_ADD_START)
end procedure

procedure erase() is
    print_crlf(serial_hw_data)
    var byte str [] = "Erasing eeprom... "
    print_string(serial_hw_data,str)
    var byte i
    -- fill eeprom with zero

    -- for 256 using i loop does not work in JAL
    -- therefore use repeat unitl loop instead
    i = 0
    repeat
        data_eeprom_write(i,0)
        i = i + 1
    until i == 0

    var byte str2 [] = "done !"
    print_string(serial_hw_data,str2)
    print_crlf(serial_hw_data)
end procedure

procedure ask_username() is
    -- first erase all data eeprom
    erase()

    -- ok, now collect info
    var byte str1 [] = "I don't know you, please enter your name, then press [RETURN]"
    print_string(serial_hw_data,str1)
    print_crlf(serial_hw_data)

    -- read entered chars, until return press
    -- store to eeprom in the same time
    var byte char = 255
    -- until a cariage return (win/linux)
    while char >= 32 loop
        -- check if something entered
        if serial_hw_read(char) == true then
            store_char(char)
            -- echo char, so user knows what he's typing
            serial_hw_write(char)
        end if
    end loop

    -- print a EOF (end-of-frame) char to mark end of input
    -- will used to extract username later
    store_char(4)

    print_crlf(serial_hw_data)
    const str2 [] = "Thanks !"
    print_crlf(serial_hw_data)
end procedure

-- erase all, from scratch if needed...
;;erase()

forever loop
    -- back to the beginning of data
    reset()

    var byte str1 [] = "Hi, "
    print_string(serial_hw_data,str1)
    -- extract username
    var byte char = 0
    -- print until reach previously stored EOF
    -- or end of data eeprom memory
    var byte counter = 0
    while (counter != 255) & (char != 4) loop
        char = read_char()
        serial_hw_data = char
        counter = counter + 1
    end loop
    print_crlf(serial_hw_data)
    var byte str2 [] = "(press '$' to enter your name...)"
    print_string(serial_hw_data,str2)
    print_crlf(serial_hw_data)

    -- wait for user input
    while serial_hw_read(char) == false loop
    end loop

    if char == "$" then
        ask_username()
    end if
end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_eeprom_read_dword - JALlib Procedures Help

data_eeprom_read_dword JALLIB PROCEDURE

Signature

procedure data_eeprom_read_dword(word in offset, dword out data) is

Description

Title: Read doubleword from data EEPROM at given offset
Arguments: - Offset in data EEPROM of doubleword to be read
- Data (dword) to store EEPROM contents
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in
  • data - dword out

Return Value

None

Example

From sample file: 18f4620_rotary_encoder_e6b2.jal

-- Title: Rotary Encoder Sample
-- Author: Matthew Schinkel - justanotherlanguage.org, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Counts the rotation of a rotary encoder using interrupt on change
--              pins. Position is stored in eeprom for next power on.
--              I tested with encoder OMRON E6B2-CWZ6C 2000P/R with pull up
--              resistors. I may use E6B2-CWZ3E in the future so there
--              is no need for a pull up resistor. This lib may work with other
--              rotary encoders.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.mouser.com/ds/2/307/e6b2-c_ds_csm491-25665.pdf
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT  -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

include delay
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include pic_data_eeprom

-- alias the interrupt flags so they are readable.
alias INT_0_ENABLE_BIT is INTCON_INT0IE
alias INT_0_FLAG_BIT is INTCON_INT0IF
alias INT_0_EDGE_BIT is INTCON2_INTEDG0

-- enable global interrupts
INTCON_GIE  = TRUE        -- Enables all unmasked interrupts
INTCON_PEIE = TRUE        -- Enables all unmasked peripheral interrupts

-- define rotary encoder pins
alias re1_a is pin_B0
alias re1_a_direction is pin_B0_direction
re1_a_direction = INPUT
--
alias re1_b is pin_B1
alias re1_b_direction is pin_B1_direction
re1_b_direction = INPUT
--
-- rotery encoder z pin is not required
;alias re1_z is pin_B2
;alias re1_z_direction is pin_B1_direction
;re1_z_direction = INPUT

-- enable interrupt on change pin
INT_0_ENABLE_BIT = TRUE   -- interrupt pin enable bit for B0
procedure rotery_encoder_changed() -- procedure is written later

-- main interrupt handler
procedure re_interrupt() is
   pragma interrupt
   -- Check if interrupt pin 0 (B0 re1_a) has an interrupt.
   if INT_0_FLAG_BIT then
      rotery_encoder_changed() -- call our rotery encoder procedure
      INT_0_FLAG_BIT = FALSE -- reset interrupt flag
   end if
end procedure

-- variable to count position
var sdword int_count
var dword int_count_temp
data_eeprom_read_dword(0,int_count_temp)
int_count = sword(int_count_temp) + 1

-- interrupt for pin B0
-- try not to do much in here
procedure rotery_encoder_changed() is
   pragma inline

   if re1_b == HIGH then
      int_count = int_count + 1
   else
      int_count = int_count - 1
   end if
end procedure

-- Set the current position (default is 0)
procedure re1_set_position(sdword in center) is
   data_eeprom_write_dword(0,dword(center))
   int_count = center
end procedure

-- Set the center position (add a button?)
;re1_set_position(0)

-- report current position
print_sdword_dec(serial_data,int_count)
print_crlf(serial_data)

-- Create clock pulses to trigger our interrupt
-- Connect this output to pin B0.
var sdword int_count_prev
forever loop
   -- print only when position changes
   if int_count != int_count_prev then
      -- store value in eeprom for next power on
      data_eeprom_write_dword(0,dword(int_count - 1))

      -- report the position
      print_sdword_dec(serial_data,int_count)
      print_crlf(serial_data)

      int_count_prev = int_count
   end if
end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_eeprom_read_word - JALlib Procedures Help

data_eeprom_read_word JALLIB PROCEDURE

Signature

procedure data_eeprom_read_word(word in offset, word out data) is

Description

Title: Read word from data EEPROM at given offset
Arguments: - Offset in data EEPROM of word to be read
- Data (word) to store EEPROM contents
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in
  • data - word out

Return Value

None

Example

From sample file: 16f876a_rtc_timeset.jal

-- Title: Sample program to show usage of rtc_isr, with a time set procedure
-- Author: Eur van Andel, Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber, Rob Hamerling
-- Compiler: 2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:  http://www.romanblack.com/one_sec.htm, http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
--
-- Description: This program shows how to handle Real Time in a PIC,
-- complete with setting the initial time by the compiler OS
-- via the timeset.py script, which writes the now.jal file
-- The user can set the time via the timeset() procedure,
-- which uses the keyboard and LCD. This layout is tailored to a 20x4 LCD.
--
-- This file has been generated by hand (manually maintained)
--

-- ------------------- SELECT PIC ----------------------------
include 16f876a

pragma target clock     20_000_000           -- 20 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

T0CON_T0CS = 0                               -- internal instruction cycle clock
T0CON_PSA = 1                                -- prescaler assigned to Timer0 module
T0CON_T0PS = 0                               -- no prescaling

-- ------------------------ LIBRARIES ------------------------

include rtc_isr_tmr0

var byte minutes                 -- seconds in ISR lib
var byte hours

var byte date
var byte month
var word year

include now                      -- sets the time to system time + one minute
                                 -- = compile and burn time
                                 -- should be generated just before compiling

include calendar                 -- 60/24/27..31/12 range limits
pragma eedata 250                -- to check if first boot after programming

include delay                    -- used by LCD lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS                 is pin_b5       -- LCD command/data select.
alias LCD_EN                 is pin_b4       -- LCD data trigger
alias LCD_dataport           is portb_low    -- LCD data nibble
portb_direction              = all_output    -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting
include pic_data_eeprom                      -- to save time when no power

var byte dummy
alias keyscan  is portc_low                  -- rows of keyboard
portc_low_direction = all_input
alias keydrive is portb_low                  -- columns of keyboard, also LCD data
var byte keydrive_direction = dummy
include keyboard                             -- read for schematics

-- ------------------------ PROCEDURES ------------------------

procedure time_set() is
lcd_clear_screen()
while getkey() != 0x0C loop        -- wait until C, bottom right key

   lcd_cursor_position(0,0)
   const byte str4[] = "timeset menu C=exit"
   print_string(lcd, str4)

   lcd_cursor_position(1,0)
   format_time_hms(lcd, hours, minutes, seconds)
   lcd = " "
   print_byte_dec(lcd, date)
   lcd = "-"
   print_byte_dec(lcd, month)
   lcd = "-"
   print_word_dec(lcd, year)
   lcd = " "

   const byte str5[] = " 1  2 use 3  F   7"
   const byte str6[] = " 4  5 key 6  E   A"
   lcd_cursor_position(2,0)                           -- line 3
   print_string(lcd, str5)
   lcd_cursor_position(3,0)                           -- line 4
   print_string(lcd, str6)

   if getkey() == 1 then
      hours = hours + 1
         if hours > 23 then
               hours = hours - 24
         end if
   end if
   if getkey() == 4 then  hours = hours - 1
      if hours > 127 then     -- through zero
         hours = hours + 24      -- 255 + 24 = 23
      end if
   end if
   if getkey() == 2 then  minutes = minutes + 1
      if minutes > 59 then
         minutes = minutes - 60
      end if
   end if
   if getkey() == 5 then  minutes = minutes - 1
      if minutes > 127 then      -- through zero
         minutes = minutes + 60  -- 255 + 60 = 59
      end if
   end if
   if getkey() == 3 then  date = date + 1
      if date > 31 then
         date = date - 31
      end if
   end if
   if getkey() == 6 then  date = date - 1
      if date > 127 then      -- through zero
         date = date + 32     -- 255 + 32 = 31
      end if
   end if
   if getkey() == 0x0F then  month = month + 1
      if month > 12 then
         month = month - 12
      end if
   end if
   if getkey() == 0x0E then  month = month - 1
      if month > 127 then
         month = month + 13      -- 255 +13 = 12
      end if
   end if
   if getkey() == 7 then
      year = year + 1
   end if
   if getkey() == 0x0A then
      year = year - 1
   end if

   calendar

   delay_100ms(2)

end loop       -- getkey() = # or 0x0F
-- time is set here, ISR can be off
data_eeprom_write(0, minutes)
data_eeprom_write(1, hours)
data_eeprom_write(2, date)
data_eeprom_write(3, month)
data_eeprom_write_word(4, year)

lcd_clear_screen()
end procedure        -- ----------------- TIME SET  ----------------------

-- -------------------------- START PROGRAM -----------------

if data_eeprom(0) != 250 then       -- not first boot after programming
   seconds = 0                      -- time isn't accurate anyway
   data_eeprom_read(0, minutes)     -- get old time from eeprom
   data_eeprom_read(1, hours)
   data_eeprom_read(2, date)
   data_eeprom_read(3, month)
   data_eeprom_read_word(4, year)
else
   data_eeprom_write(0, minutes)    -- save present time to eeprom
   data_eeprom_write(1, hours)      -- present time comes from now.jal
   data_eeprom_write(2, date)
   data_eeprom_write(3, month)
   data_eeprom_write_word(4, year)
end if

INTCON_TMR0IE = on                  -- if your PIC freezes, comment these lines
INTCON_GIE = on                     -- to see if the ISR is messed up

lcd_clear_screen()
forever  loop
   lcd_cursor_position(0,0)
   const byte str1[] = "Time RTC sample"
   print_string(lcd, str1)

   lcd_cursor_position(1,0)
   print_byte_dec(lcd, date)
   lcd = "-"
   print_byte_dec(lcd, month)
   lcd = "-"
   print_word_dec(lcd, year)
   lcd = " "
   if seconds > 59 then
      calendar()
   end if
   format_time_hms(lcd, hours, minutes, seconds)

   lcd_cursor_position(3,0)             -- fourth line
   const byte str3[] = "press 9 to set time"
   print_string(lcd, str3)
   if getkey() == 9 then
      time_set()
   end if

   delay_100ms(2)                      -- for LCD viewing

end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_eeprom_write - JALlib Procedures Help

data_eeprom_write JALLIB PROCEDURE

Signature

procedure data_eeprom_write(word in offset, byte in data) is

Description

Title: Write byte to data EEPROM at given offset
Arguments: - Offset in data EEPROM of byte to be written
- Data (byte) to be stored in data EEPROM
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in
  • data - byte in

Return Value

None

Example

From sample file: 16f88_remember_me.jal

-- Title: Sample showing basic read/write operations on data eeprom
-- Author: Sebastien Lelong, Copyright (c) 2008, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4g
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows a basic usage to read from and write to data eeprom.
-- The first time, it asks for your name, complaining it does not know you...
-- Enter your name, then turn off the PIC. Turn on, it still knows you. Amazing !
-- --
-- You can re-enter your name again, by entering "$" (1 dollar sign) to switch to
-- input mode. This is a basic example of how to implement a read/eval/print/loop (REPL)
--
-- This file has been generated by hand (manually maintained)
--
-- Input/Output:
-- [open your favorite serial term]
-- [turn on your PIC, you should have something like...]
-- Hi,
-- (press '$' to enter your name...)
-- [follow instructions]
-- Erasing eeprom... done !
-- I don't know you, please enter your name, then press [RETURN]
-- Sebastien Lelong
-- Hi, Sebastien Lelong
-- (press '$' to enter your name...)
-- [turn off/on PIC, it remembers you !]
-- Hi, Sebastien Lelong
-- (press '$' to enter your name...)

include 16f88
-- set all IO as digital
enable_digital_io()

-- We'll use internal oscillator. It work @ 8MHz
pragma target clock		8_000_000
pragma target OSC		INTOSC_NOCLKOUT
-- Specify no postscaler, ie. really runs @8MHz
OSCCON_IRCF = 0b_111
-- no watchdog, please
pragma target WDT		disabled

-- ok, now setup serial
-- we want to use USART/RS232, not SPI
const usart_hw_serial = true	-- true = RS232, false = SPI
-- setup speed. Standard values are: 57_600, 19_200, 9_600, 2_400, ...
const serial_hw_baudrate = 19_200
-- now we can use serial_hardware module
include serial_hardware
-- initialize the whole with our parameters
serial_hw_init()

include pic_data_eeprom
include print

-- This is where we start reading/writing
-- We could start from 0, but for fun (...),
-- we'll start at 10.
const EEPROM_ADD_START = 10
-- We'll also use a counter to know where we are
var byte eeprom_counter = 0

-- Because we don't want to handle eeprom address logic
-- everywhere in the code, we defines convinient functions
-- and procedures
--
-- store a char, and set next eeprom position
procedure store_char(byte in char) is
    data_eeprom_write(EEPROM_ADD_START + eeprom_counter,char)
    eeprom_counter = eeprom_counter + 1
end procedure

-- read char from eeprom, at current address, then
-- set to next eeprom position
function read_char() return byte is
    var byte char
    data_eeprom_read(EEPROM_ADD_START + eeprom_counter,char)
    eeprom_counter = eeprom_counter + 1
    return char
end function

procedure reset() is
    eeprom_counter = byte(EEPROM_ADD_START)
end procedure

procedure erase() is
    print_crlf(serial_hw_data)
    var byte str [] = "Erasing eeprom... "
    print_string(serial_hw_data,str)
    var byte i
    -- fill eeprom with zero

    -- for 256 using i loop does not work in JAL
    -- therefore use repeat unitl loop instead
    i = 0
    repeat
        data_eeprom_write(i,0)
        i = i + 1
    until i == 0

    var byte str2 [] = "done !"
    print_string(serial_hw_data,str2)
    print_crlf(serial_hw_data)
end procedure

procedure ask_username() is
    -- first erase all data eeprom
    erase()

    -- ok, now collect info
    var byte str1 [] = "I don't know you, please enter your name, then press [RETURN]"
    print_string(serial_hw_data,str1)
    print_crlf(serial_hw_data)

    -- read entered chars, until return press
    -- store to eeprom in the same time
    var byte char = 255
    -- until a cariage return (win/linux)
    while char >= 32 loop
        -- check if something entered
        if serial_hw_read(char) == true then
            store_char(char)
            -- echo char, so user knows what he's typing
            serial_hw_write(char)
        end if
    end loop

    -- print a EOF (end-of-frame) char to mark end of input
    -- will used to extract username later
    store_char(4)

    print_crlf(serial_hw_data)
    const str2 [] = "Thanks !"
    print_crlf(serial_hw_data)
end procedure

-- erase all, from scratch if needed...
;;erase()

forever loop
    -- back to the beginning of data
    reset()

    var byte str1 [] = "Hi, "
    print_string(serial_hw_data,str1)
    -- extract username
    var byte char = 0
    -- print until reach previously stored EOF
    -- or end of data eeprom memory
    var byte counter = 0
    while (counter != 255) & (char != 4) loop
        char = read_char()
        serial_hw_data = char
        counter = counter + 1
    end loop
    print_crlf(serial_hw_data)
    var byte str2 [] = "(press '$' to enter your name...)"
    print_string(serial_hw_data,str2)
    print_crlf(serial_hw_data)

    -- wait for user input
    while serial_hw_read(char) == false loop
    end loop

    if char == "$" then
        ask_username()
    end if
end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_eeprom_write_dword - JALlib Procedures Help

data_eeprom_write_dword JALLIB PROCEDURE

Signature

procedure data_eeprom_write_dword(word in offset, dword in data) is

Description

Title: Write doubleword to data EEPROM at given offset
Arguments: - Offset in data EEPROM of doubleword to be written
- Data (dword) to be stored
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in
  • data - dword in

Return Value

None

Example

From sample file: 18f4620_rotary_encoder_e6b2.jal

-- Title: Rotary Encoder Sample
-- Author: Matthew Schinkel - justanotherlanguage.org, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Counts the rotation of a rotary encoder using interrupt on change
--              pins. Position is stored in eeprom for next power on.
--              I tested with encoder OMRON E6B2-CWZ6C 2000P/R with pull up
--              resistors. I may use E6B2-CWZ3E in the future so there
--              is no need for a pull up resistor. This lib may work with other
--              rotary encoders.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.mouser.com/ds/2/307/e6b2-c_ds_csm491-25665.pdf
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT  -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

include delay
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include pic_data_eeprom

-- alias the interrupt flags so they are readable.
alias INT_0_ENABLE_BIT is INTCON_INT0IE
alias INT_0_FLAG_BIT is INTCON_INT0IF
alias INT_0_EDGE_BIT is INTCON2_INTEDG0

-- enable global interrupts
INTCON_GIE  = TRUE        -- Enables all unmasked interrupts
INTCON_PEIE = TRUE        -- Enables all unmasked peripheral interrupts

-- define rotary encoder pins
alias re1_a is pin_B0
alias re1_a_direction is pin_B0_direction
re1_a_direction = INPUT
--
alias re1_b is pin_B1
alias re1_b_direction is pin_B1_direction
re1_b_direction = INPUT
--
-- rotery encoder z pin is not required
;alias re1_z is pin_B2
;alias re1_z_direction is pin_B1_direction
;re1_z_direction = INPUT

-- enable interrupt on change pin
INT_0_ENABLE_BIT = TRUE   -- interrupt pin enable bit for B0
procedure rotery_encoder_changed() -- procedure is written later

-- main interrupt handler
procedure re_interrupt() is
   pragma interrupt
   -- Check if interrupt pin 0 (B0 re1_a) has an interrupt.
   if INT_0_FLAG_BIT then
      rotery_encoder_changed() -- call our rotery encoder procedure
      INT_0_FLAG_BIT = FALSE -- reset interrupt flag
   end if
end procedure

-- variable to count position
var sdword int_count
var dword int_count_temp
data_eeprom_read_dword(0,int_count_temp)
int_count = sword(int_count_temp) + 1

-- interrupt for pin B0
-- try not to do much in here
procedure rotery_encoder_changed() is
   pragma inline

   if re1_b == HIGH then
      int_count = int_count + 1
   else
      int_count = int_count - 1
   end if
end procedure

-- Set the current position (default is 0)
procedure re1_set_position(sdword in center) is
   data_eeprom_write_dword(0,dword(center))
   int_count = center
end procedure

-- Set the center position (add a button?)
;re1_set_position(0)

-- report current position
print_sdword_dec(serial_data,int_count)
print_crlf(serial_data)

-- Create clock pulses to trigger our interrupt
-- Connect this output to pin B0.
var sdword int_count_prev
forever loop
   -- print only when position changes
   if int_count != int_count_prev then
      -- store value in eeprom for next power on
      data_eeprom_write_dword(0,dword(int_count - 1))

      -- report the position
      print_sdword_dec(serial_data,int_count)
      print_crlf(serial_data)

      int_count_prev = int_count
   end if
end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_eeprom_write_word - JALlib Procedures Help

data_eeprom_write_word JALLIB PROCEDURE

Signature

procedure data_eeprom_write_word(word in offset, word in data) is

Description

Title: Write word to data EEPROM at given offset
Arguments: - Offset in data EEPROM of word to be written
- Data (word) to store in EEPROM
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_eeprom

Parameters

  • offset - word in
  • data - word in

Return Value

None

Example

From sample file: 16f876a_rtc_timeset.jal

-- Title: Sample program to show usage of rtc_isr, with a time set procedure
-- Author: Eur van Andel, Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber, Rob Hamerling
-- Compiler: 2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:  http://www.romanblack.com/one_sec.htm, http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
--
-- Description: This program shows how to handle Real Time in a PIC,
-- complete with setting the initial time by the compiler OS
-- via the timeset.py script, which writes the now.jal file
-- The user can set the time via the timeset() procedure,
-- which uses the keyboard and LCD. This layout is tailored to a 20x4 LCD.
--
-- This file has been generated by hand (manually maintained)
--

-- ------------------- SELECT PIC ----------------------------
include 16f876a

pragma target clock     20_000_000           -- 20 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

T0CON_T0CS = 0                               -- internal instruction cycle clock
T0CON_PSA = 1                                -- prescaler assigned to Timer0 module
T0CON_T0PS = 0                               -- no prescaling

-- ------------------------ LIBRARIES ------------------------

include rtc_isr_tmr0

var byte minutes                 -- seconds in ISR lib
var byte hours

var byte date
var byte month
var word year

include now                      -- sets the time to system time + one minute
                                 -- = compile and burn time
                                 -- should be generated just before compiling

include calendar                 -- 60/24/27..31/12 range limits
pragma eedata 250                -- to check if first boot after programming

include delay                    -- used by LCD lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS                 is pin_b5       -- LCD command/data select.
alias LCD_EN                 is pin_b4       -- LCD data trigger
alias LCD_dataport           is portb_low    -- LCD data nibble
portb_direction              = all_output    -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting
include pic_data_eeprom                      -- to save time when no power

var byte dummy
alias keyscan  is portc_low                  -- rows of keyboard
portc_low_direction = all_input
alias keydrive is portb_low                  -- columns of keyboard, also LCD data
var byte keydrive_direction = dummy
include keyboard                             -- read for schematics

-- ------------------------ PROCEDURES ------------------------

procedure time_set() is
lcd_clear_screen()
while getkey() != 0x0C loop        -- wait until C, bottom right key

   lcd_cursor_position(0,0)
   const byte str4[] = "timeset menu C=exit"
   print_string(lcd, str4)

   lcd_cursor_position(1,0)
   format_time_hms(lcd, hours, minutes, seconds)
   lcd = " "
   print_byte_dec(lcd, date)
   lcd = "-"
   print_byte_dec(lcd, month)
   lcd = "-"
   print_word_dec(lcd, year)
   lcd = " "

   const byte str5[] = " 1  2 use 3  F   7"
   const byte str6[] = " 4  5 key 6  E   A"
   lcd_cursor_position(2,0)                           -- line 3
   print_string(lcd, str5)
   lcd_cursor_position(3,0)                           -- line 4
   print_string(lcd, str6)

   if getkey() == 1 then
      hours = hours + 1
         if hours > 23 then
               hours = hours - 24
         end if
   end if
   if getkey() == 4 then  hours = hours - 1
      if hours > 127 then     -- through zero
         hours = hours + 24      -- 255 + 24 = 23
      end if
   end if
   if getkey() == 2 then  minutes = minutes + 1
      if minutes > 59 then
         minutes = minutes - 60
      end if
   end if
   if getkey() == 5 then  minutes = minutes - 1
      if minutes > 127 then      -- through zero
         minutes = minutes + 60  -- 255 + 60 = 59
      end if
   end if
   if getkey() == 3 then  date = date + 1
      if date > 31 then
         date = date - 31
      end if
   end if
   if getkey() == 6 then  date = date - 1
      if date > 127 then      -- through zero
         date = date + 32     -- 255 + 32 = 31
      end if
   end if
   if getkey() == 0x0F then  month = month + 1
      if month > 12 then
         month = month - 12
      end if
   end if
   if getkey() == 0x0E then  month = month - 1
      if month > 127 then
         month = month + 13      -- 255 +13 = 12
      end if
   end if
   if getkey() == 7 then
      year = year + 1
   end if
   if getkey() == 0x0A then
      year = year - 1
   end if

   calendar

   delay_100ms(2)

end loop       -- getkey() = # or 0x0F
-- time is set here, ISR can be off
data_eeprom_write(0, minutes)
data_eeprom_write(1, hours)
data_eeprom_write(2, date)
data_eeprom_write(3, month)
data_eeprom_write_word(4, year)

lcd_clear_screen()
end procedure        -- ----------------- TIME SET  ----------------------

-- -------------------------- START PROGRAM -----------------

if data_eeprom(0) != 250 then       -- not first boot after programming
   seconds = 0                      -- time isn't accurate anyway
   data_eeprom_read(0, minutes)     -- get old time from eeprom
   data_eeprom_read(1, hours)
   data_eeprom_read(2, date)
   data_eeprom_read(3, month)
   data_eeprom_read_word(4, year)
else
   data_eeprom_write(0, minutes)    -- save present time to eeprom
   data_eeprom_write(1, hours)      -- present time comes from now.jal
   data_eeprom_write(2, date)
   data_eeprom_write(3, month)
   data_eeprom_write_word(4, year)
end if

INTCON_TMR0IE = on                  -- if your PIC freezes, comment these lines
INTCON_GIE = on                     -- to see if the ISR is messed up

lcd_clear_screen()
forever  loop
   lcd_cursor_position(0,0)
   const byte str1[] = "Time RTC sample"
   print_string(lcd, str1)

   lcd_cursor_position(1,0)
   print_byte_dec(lcd, date)
   lcd = "-"
   print_byte_dec(lcd, month)
   lcd = "-"
   print_word_dec(lcd, year)
   lcd = " "
   if seconds > 59 then
      calendar()
   end if
   format_time_hms(lcd, hours, minutes, seconds)

   lcd_cursor_position(3,0)             -- fourth line
   const byte str3[] = "press 9 to set time"
   print_string(lcd, str3)
   if getkey() == 9 then
      time_set()
   end if

   delay_100ms(2)                      -- for LCD viewing

end loop

Generated by JALlib CHM Help System | Source: pic_data_eeprom.jal


data_hef - JALlib Procedures Help

data_hef JALLIB FUNCTION

Signature

function data_hef(word in offset) return byte is

Description

Title: Read byte of data HEF at given offset
Arguments: Offset in data HEF of byte to be read
Returns: Byte of data HEF

Include

To use this procedure, include the library:

include pic_data_hef

Parameters

  • offset - word in

Return Value

byte - Byte of data HEF

Example

From sample file: 16f1765_data_hef.jal

-- -----------------------------------------------------------------------------
-- Title: Sample data HEF write and read for the Microchip PIC16F1765
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Sample data HEF write and read for the Microchip PIC16F1765.
--              During HEF writing and reading the LED is blinking. After
--              verifying all HEF addresses successfully the LED should stay on.
--              If the data read is not the same as the data written the LED
--              will be off.
--
-- Sources:
--
-- Notes:
--

-- chip setup
include 16f1765

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz

-- Make all pins digital I/O instead of analog.
enable_digital_io()

-- High Endurance Flash (HEF) address declarations.
const HEF_NR_OF_BYTES    = 128
const HEF_ADDRESS_OFFSET = 8192 - HEF_NR_OF_BYTES
include pic_data_hef

-- LED IO definition
alias led             is pin_a0
alias led_direction   is pin_a0_direction
led_direction = output

var byte i,j
var bit led_value = ON
var bit all_ok = TRUE

led = OFF
i = 0

forever loop
   _usec_delay(100_000)

   -- As long as the led blinks all written data equals the data is read back.
   -- In case of a difference in data the led will be turned off. After a
   -- succesfull write and read cycle of HEF_NR_OF_BYTES bytes the LED stays on.
   if all_ok then
      led_value = !led_value   -- toggle the led
      data_hef_write(i,i)      -- write value
      j = data_hef(i)          -- read back
      if (j != i) then
         all_ok = FALSE
         led_value = OFF
      end if
   end if
   i = i + 1

   led = led_value

   if (i == HEF_NR_OF_BYTES) then
      -- Final check, see if values where not overwritten.
      j = 0
      while all_ok & (j < HEF_NR_OF_BYTES) loop
         if (j != data_hef(j)) then
            all_ok = FALSE -- Error, data was overwritten.
         end if
         j = j + 1
      end loop
      if all_ok then
          led = ON
      else
         led = OFF
      end if
      while true loop
         -- This will never end.
      end loop
   end if

end loop

Generated by JALlib CHM Help System | Source: pic_data_hef.jal


data_hef_write - JALlib Procedures Help

data_hef_write JALLIB PROCEDURE

Signature

procedure data_hef_write(word in offset, byte in data) is

Description

Title: Write byte to data HEF at given offset
Arguments: - Offset of data HEF of byte to be written
- Data (byte) to be stored in data HEF
Returns: (nothing)

Include

To use this procedure, include the library:

include pic_data_hef

Parameters

  • offset - word in
  • data - byte in

Return Value

None

Example

From sample file: 16f1765_data_hef.jal

-- -----------------------------------------------------------------------------
-- Title: Sample data HEF write and read for the Microchip PIC16F1765
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Sample data HEF write and read for the Microchip PIC16F1765.
--              During HEF writing and reading the LED is blinking. After
--              verifying all HEF addresses successfully the LED should stay on.
--              If the data read is not the same as the data written the LED
--              will be off.
--
-- Sources:
--
-- Notes:
--

-- chip setup
include 16f1765

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz

-- Make all pins digital I/O instead of analog.
enable_digital_io()

-- High Endurance Flash (HEF) address declarations.
const HEF_NR_OF_BYTES    = 128
const HEF_ADDRESS_OFFSET = 8192 - HEF_NR_OF_BYTES
include pic_data_hef

-- LED IO definition
alias led             is pin_a0
alias led_direction   is pin_a0_direction
led_direction = output

var byte i,j
var bit led_value = ON
var bit all_ok = TRUE

led = OFF
i = 0

forever loop
   _usec_delay(100_000)

   -- As long as the led blinks all written data equals the data is read back.
   -- In case of a difference in data the led will be turned off. After a
   -- succesfull write and read cycle of HEF_NR_OF_BYTES bytes the LED stays on.
   if all_ok then
      led_value = !led_value   -- toggle the led
      data_hef_write(i,i)      -- write value
      j = data_hef(i)          -- read back
      if (j != i) then
         all_ok = FALSE
         led_value = OFF
      end if
   end if
   i = i + 1

   led = led_value

   if (i == HEF_NR_OF_BYTES) then
      -- Final check, see if values where not overwritten.
      j = 0
      while all_ok & (j < HEF_NR_OF_BYTES) loop
         if (j != data_hef(j)) then
            all_ok = FALSE -- Error, data was overwritten.
         end if
         j = j + 1
      end loop
      if all_ok then
          led = ON
      else
         led = OFF
      end if
      while true loop
         -- This will never end.
      end loop
   end if

end loop

Generated by JALlib CHM Help System | Source: pic_data_hef.jal


dcf77_decoder.jal - JALLIB Library Documentation

dcf77_decoder.jal JALLIB LIBRARY

Title

DCF77 Decoder Library.

Author

Rob Jansen, Copyright (c) 2023..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for decoding the DCF77 format. The library
can be configured to use either the external interrupt or an
IOC interrupt to decode the DCF77 Message.
The default is using an external interrupt. In order to switch
to using an IOC interrupt the user must initialize the IOC
to be active on both the rising and falling edge and must
define the following alias (example for IOC on pin A2):
alias dcf77_decoder_ioc_flag is IOCAF_IOCAF2
The library uses Timer 1 to measure the the bit-times
The user must initialize Timer 1 to overflow every 1 ms. For
that the constant DCF77_TIMER_1_RELOAD must be defined by
the main program to generate an overflow after 1 ms.

Notes

A DCF77 receiver must be connected to the external interrupt pin
or the used IOC pin. Receivers can be active low or active
high. The default setting is active high but this can be changed
to active low.

Sources

Technical Note: Overview of DCF77 Time Protocol TN-103, SEP-2017.
https://en.wikipedia.org/wiki/DCF77

----------------------------------------------------------------------------
-------------------------- Public API --------------------------------------
----------------------------------------------------------------------------

----------------------------------------------------------------------------
Initialize the DCF77 Decoder. This will initialize timer 1 and will enable
the required interrupts.
----------------------------------------------------------------------------

Routines

  • _dcf77_handle_interrupt_flag - Function returns bit
  • _dcf77_reset_decoder - Procedure
  • _dcf77_timer1_interrupt - Procedure
  • _dcf_interrupt - Procedure
  • dcf77_decoder_init - Procedure
  • dcf77_decoder_pulse_high - Procedure
  • dcf77_decoder_pulse_low - Procedure
  • dcf77_get_day_of_month - Function returns byte
  • dcf77_get_day_of_week - Function returns byte
  • dcf77_get_hours - Function returns byte
  • dcf77_get_minutes - Function returns byte
  • dcf77_get_month - Function returns byte
  • dcf77_get_year_within_century - Function returns byte
  • dcf77_message_received - Function returns bit
  • dcf77_time_is_cest - Function returns bit
  • dcf77_time_is_cet - Function returns bit


dcf77_decoder_init - JALlib Procedures Help

dcf77_decoder_init JALLIB PROCEDURE

Signature

procedure dcf77_decoder_init() is

Description

Initialize the DCF77 Decoder. This will enable the required interrupts. The
decoder is set to decode an incomming stream that uses an active high pulse.

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

None

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_get_day_of_month - JALlib Procedures Help

dcf77_get_day_of_month JALLIB FUNCTION

Signature

function dcf77_get_day_of_month() return byte is

Description

Returns the day of the month (1..31).

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_get_day_of_week - JALlib Procedures Help

dcf77_get_day_of_week JALLIB FUNCTION

Signature

function dcf77_get_day_of_week() return byte is

Description

Returns the day of the week (1..7), where day 1 is Monday and 7 is Sunday.

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_get_hours - JALlib Procedures Help

dcf77_get_hours JALLIB FUNCTION

Signature

function dcf77_get_hours() return byte is

Description

Returns the received hours. Hours are BCD coded.

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_get_minutes - JALlib Procedures Help

dcf77_get_minutes JALLIB FUNCTION

Signature

function dcf77_get_minutes() return byte is

Description

Returns the received minuted. Minutes are BCD coded.

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_get_month - JALlib Procedures Help

dcf77_get_month JALLIB FUNCTION

Signature

function dcf77_get_month() return byte is

Description

Returns the month (1..12).

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_get_year_within_century - JALlib Procedures Help

dcf77_get_year_within_century JALLIB FUNCTION

Signature

function dcf77_get_year_within_century() return byte is

Description

Returns the year wihin the century (0..99).

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_message_received - JALlib Procedures Help

dcf77_message_received JALLIB FUNCTION

Signature

function dcf77_message_received() return bit is

Description

Returns TRUE when a valid DCF77 message was received. Calling this function
will clear the message received flag and will enable the reception of the
next DCF77 message.

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_time_is_cest - JALlib Procedures Help

dcf77_time_is_cest JALLIB FUNCTION

Signature

function dcf77_time_is_cest() return bit is

Description

Returns TRUE if the time is Central European Summer Time (CEST).

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dcf77_time_is_cet - JALlib Procedures Help

dcf77_time_is_cet JALLIB FUNCTION

Signature

function dcf77_time_is_cet() return bit is

Description

Returns TRUE if the time is Central European Time (CET).

Include

To use this procedure, include the library:

include dcf77_decoder

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_dcf77_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DCF77 Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the DCF77 decoder
--              library. The sample program shows a software clock with time,
--              date and day of the week which is synchronized with the
--              information given by the DCF77 transmiter.
--              The serial interface is used to display the information.
--              The DCF77 library uses timer 1 to measure the bit-times. This
--              timer must be set to overflow every 1 ms.
--
-- Note:        The PIC runs at a low internal clock of 4 MHz since the DCF77
--              signal has a low bitrate. This will also reduce the amonunt of
--              noise generated by the PIC and so increase sensitivity.
--
include 16f1825

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 4 MHz.
OSCCON_IRCF   = 0b1101                 -- Set 4 MHz
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC

-- Enable weak pull up. Weak pull-up on the interrupt pin is not needed.
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print
-- Settings for the DCF77 Decoder. The decoder uses timer 1 to get an overflow
-- interrupt every 1 ms. In this case we use Fosc/4 and a prescaler of 1:8 to
-- get a 1 MHz timer 1 clock since the target clock is at 4 MHz.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 1 MHz.
T1CON_T1CKPS = 0b00 -- Prescaler 1:1, gives 1 MHz.
-- Set the timer 1 reload value to get an overflow after 1 ms time. Timer is
-- running at 1 MHz.
const word DCF77_TIMER_1_RELOAD = 65535 - 1_000

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the DCF77 decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias dcf77_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias dcf77_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias dcf77_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if

-- Now we can include the library.
include dcf77_decoder
dcf77_decoder_init()

-- Variables.
var word second_counter
var byte hours, minutes, seconds
var byte day, month, year
var bit  second_passed

-- Timer 2 interrupt procedure. Sets a 1 second flag.
procedure timer_2_interrupt() is
   pragma interrupt

   if PIR1_TMR2IF then
      PIR1_TMR2IF = FALSE
      second_counter = second_counter + 1
      if (second_counter == 1_000) then
         second_counter = 0
         second_passed = TRUE
      end if
   end if

end procedure

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial = "0"
   end if
   print_byte_dec(serial, value)
end procedure

-- Print the given day of the week.
procedure print_day(byte in day) is

   case day of
      1: print_string(serial, "Monday")
      2: print_string(serial, "Tuesday")
      3: print_string(serial, "Wednesday")
      4: print_string(serial, "Thursday")
      5: print_string(serial, "Friday")
      6: print_string(serial, "Saturday")
      7: print_string(serial, "Sunday")
   end case

end procedure

-- Main program starts here.
hours = 0
minutes = 0
seconds = 0

-- Make a timer that can give a signal of 1 second for the sofware clock.
-- Use Timer 2. Register PR2 holds the PWM Timer Period using the following
-- formula: Period = (PR2 + 1) * 4 * Tosc * prescale value * postscale value
-- where Tosc = 1/Fosc and Fosc = 4 MHz.Setting the prescaler to 4 and PR2
-- at 249: (249 + 1) * 4 * 1/4.000.000 * 4 * 1 = 1 ms. Period Cycle = 1 kHz.
T2CON_TMR2ON = FALSE
T2CON_T2OUTPS = 0b0000 -- Postscaler is 1:1 (no postscaling).
T2CON_T2CKPS = 0b01    -- Prescaler divide by 4
PR2 = 249
PIE1_TMR2IE = TRUE
INTCON_PEIE = TRUE
T2CON_TMR2ON = TRUE

print_string(serial, "Sample program for the DCF77 decoder\r\n")

forever  loop

   -- Run the software clock.
   if second_passed then
      second_passed = FALSE
      seconds = seconds + 1
      if (seconds == 60) then
         seconds = 0
         minutes = minutes + 1
         if (minutes == 60) then
            minutes = 0
            hours = hours + 1
            if (hours == 24) then
               hours = 0
            end if
         end if
      end if
      -- Write the clock.
      print_string(serial, "Time: ")
      print_decimal(hours)
      serial = ":"
      print_decimal(minutes)
      serial = ":"
      print_decimal(seconds)
      print_crlf(serial)
   end if

   -- See if we can synchronize our clock with the DCF77 time.
   if dcf77_message_received() then
      -- We only get hours and minutes, assume seconds is zero.
      seconds = 0
      hours = dcf77_get_hours()
      minutes = dcf77_get_minutes()

      -- Print the other DCF77 information.
      -- CET or CEST.
      if dcf77_time_is_cet() then
         print_string(serial, "Time is Central European Time.\r\n")
      elsif dcf77_time_is_cest() then
         print_string(serial, "Time is Central European Summer Time.\r\n")
      end if

      -- Day of the week.
      print_string(serial, "Day: ")
      print_day(dcf77_get_day_of_week())
      print_crlf(serial)

      -- Date.
      print_string(serial, "Date: ")
      print_decimal(dcf77_get_day_of_month())
      serial = "-"
      print_decimal(dcf77_get_month())
      print_string(serial, "-20")
      print_decimal(dcf77_get_year_within_century())
      print_crlf(serial)

   end if

end loop

Generated by JALlib CHM Help System | Source: dcf77_decoder.jal


dds_ad9833.jal - JALLIB Library Documentation

dds_ad9833.jal JALLIB LIBRARY

Title

Analog Devices AD9833 DDS Chip library

Author

Tijs van Roon@RedSam, Copyright (c) 2010, all rights reserved.

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Analog Devices AD9833 Direct-Digital-Synthesis (DDS) chip library.
--
The library assumes that the AD9833 chip is clocked 25Mhz (MCLK). If not, read the
last section to know how to change the constants to your needs.
The library is probably a very good start for other Analog DDS chips as well since
all work from the same principal.
--
Setup:
Assure that you are using a 25 Mhz oscillator on the dds chip. Otherwise change
the constant. See below (in the source) on how to do this.
First define to which pins the data,clock and fsync pins are connected and
make those pins outputs:
> pin_A4_direction = output
> pin_B7_direction = output
> pin_B5_direction = output
> alias dds_fsync_pin is pin_A4
> alias dds_sclk_pin is pin_B7
> alias dds_sdata_pin is pin_B5
Then, include the dds library
> include dds_ad9833
Reset the dds chip. This is mandatory to make it operate!
> dds_reset()
And then output a frequence with:
> dds_frequency(<freq in hz>)
Change the output shape with:
> dds_square();
> dds_sine();
> dds_triangle();
Or return to sleep mode:
> dds_sleep();
TODO:
* Automaticly calculate the constants from a dds_mclk value.
* The frequency register calculation might be done more efficient and maybe
more correct. The output frequency always seems to be a bit lower than what
is given. (I used to add a 'correction' to the FREQ0 reg, of about 2)
Other MASTERCLOCK, Changing the constants:
The DDS chip has 28-bit frequence word. When the clockspeed is known a constant
needs to be calculated which defines how many 'steps' per hz are needed to calculate
the value of the freq0 register.
The constant is calculated as follows:
<freq. output in hz> = (MCLK / 2^28) * Freg
Therefore:
Freq0 = (2^28 / MCLK) * <desired frequency output in hz>
Then 2^28 / MCLK is the constant we need.
Since this is fractional number and because at least 6 (preferably more!) digits
are needed for the calculation, the freq0 register is calculated in two steps
which together serve as a fixed point calculation. First the integral part, second
the fractional part. The fractional part is multiplied by 2^24 to gain precision
in the calculation and to make the division easier later (>>24).
Example for 25 Mhz:
steps_per_hz = 10.7274182; @ 25Mhz
Intergral part:
const dword _dds_const_int = 10;
Fractional part:
= 0.7274182 * 2^24 = 12371824
const dword _dds_const_dec = 12_371_824
CONFIGURE FREQUENCY CONSTANTS HERE!! (If needed..)
------------------------------------------------------------------------------
f = (MCLK / 2^28) * Freg => Freg = (2^28 / MCLK) * f = steps_per_hz * f
steps_per_hz = 10.73741824 @ 25Mhz
const MCLK = 25_000_000
const _dds_const_int = (1<<28) / MCLK
const _dds_const_dec = ((1<<28 / MCLK) - _dds_const_int) << 24

Routines

  • _dds_send_word - Procedure
  • dds_frequency - Procedure
  • dds_reset - Procedure
  • dds_sine - Procedure
  • dds_sleep - Procedure
  • dds_square - Procedure
  • dds_triangle - Procedure


dds_ad9850.jal - JALLIB Library Documentation

dds_ad9850.jal JALLIB LIBRARY

Title

Analog Devices AD9850 DDS Chip library

Author

Pavel Milanes Costa (c) 2013 pavelmc@gmail.com, pavel@conas.cu, co7wt@frcuba.co.cu

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Analog Devices AD9850 Direct-Digital-Synthesis (DDS) chip library.
Based on dds_ad9833.jal of Tijs van Roon@RedSam
.
The library assumes that the AD9850 chip is clocked 125Mhz (CLKIN).
If not, read the below section to know how to change the constants
to your needs.
.
Setup:
Assure that you are using a 125 Mhz oscillator on the dds chip.
Otherwise change the constant. See below on how to do this.
.
Using the library on your code:
.
Make shure you have included delay library:
> include delay
.
First define to which pins the data, clock and fsync pins are connected and
make those pins outputs:
> pin_A4_direction = output
> pin_B7_direction = output
> pin_B5_direction = output
> alias dds_sfqud_pin is pin_A4
> alias dds_sclk_pin is pin_B7
> alias dds_sdata_pin is pin_B5
.
Only if you use other OSCILLATOR than 125.000000 Mhz then you must define this
two vars... se below about how to calculate it. If not I assume 125.000 Mhz.
> dds_const_int = 34
> dds_const_dec = 6_035_408
.
Define the phase shift if it's needed, otherwise I assume 0
if you need it's a byte, from MSB to LSB the upper 5 bits are as follows
b7 (180)
b6 (90)
b5 (45)
b4 (22.5)
b3 (11.25)
the rest of the bits are ignored
.
Example I want to make a 281.25 degrees of phase LAG in this oscillator
281.25 is 180 + 90 + 11.25, then
> dds_phase_shift = 0b1100_1000
.
You can define the phase lag at any moment but it will be effective only up on
the use of dds_frequency()
.
Then, include the dds library and initialize it
> include dds_ad9850
> dds_init()
.
And then output a frequence with:
> dds_frequency(<freq in hz>)
.
Or return to sleep mode:
> dds_sleep();
.
TODO:
* Automatically calculate the constants from a dds_mclk value (NOT LIKELY)
* The frequency register calculation might be done more efficient and maybe
more correct.
.
===========================================================================
Other MASTERCLOCK, Changing the constants:
The DDS chip has 32-bit frequence word, in the datasheet it's called phase
The final freq is calculated like this:
.
fout = (phase * CLKIN) / 2^32 (fout & CLKIN in hertz)
.
And we can translate that into:
.
phase = (fout * 2^32)/CLKIN
.
We can write it in another way
.
phase = fout * (2^32/CLKIN)
.
As 2^32 and CLKIN are both fixed values we can compute (2^32/CLKIN) as a constant
for "ease" the calculation...
.
const = (2^32/CLKIN) = (2^32 / 125_000_000)
const = 34.359738368
phase = fout * 34.359738368
.
If you use another CLKIN then the phase must be calculated...
Since de floating point operation causes overflow in many ways and consume much of
our preciated ram, we must make a procedure to calculate it, how? se below
.
Splitting the calculation, in simple math and for the above example
This two equations are the same:
.
phase = fout * 34.359738368
phase = (fout * 34) + (fout * 0.359738368)
.

Constants and Variables

dds_const_int - var byte = 34
dds_const_dec - var dword = 6_035_408
dds_phase_shift - var byte = 0b0000_0000

Routines

  • _dds_send_byte - Procedure
  • dds_frequency - Procedure
  • dds_init - Procedure
  • dds_sleep - Procedure


dds_frequency - JALlib Procedures Help

dds_frequency JALLIB PROCEDURE

Signature

PROCEDURE dds_frequency(dword in hz) IS

Description

calculates the FREQ0 register word from the input frequency in hz
and sends the two control words containing the FREQ0 register to the device.

Include

To use this procedure, include the library:

include dds_ad9833

Parameters

  • hz - dword in

Return Value

None

Example

From sample file: 16f877a_dds_ad9850.jal

-- -----------------------------------------------------------------------------
-- Title: sample program for the dds_ad9850 library
-- Author: Pavel Milanes Costa, Copyright (c) 2013, all rights reserved.
--         Email: co7wt@frcuba.co.cu
--
-- Adapted-by:
--
-- Compiler:  >=2.4l
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    A sample file for the dds_ad9850 library, it's purpose is to sweep the RF
--    spectrum for the AM band (550Khz to 1.7Mhz) in increments of 10Khz, and
--    1Khz in an alternating loop
-- .
--    First sweep from 550Khz to 1.7 Mhz in 10 Khz steps
--    Second sweep from  550Khz to 1.7 Mhz in 1 Khz steps
--    repeat Frist.. Second.. etc...
-- .
--    In every step remains 500ms on freq
-- .
--    You can set your own sweep interval, steps and timings, see code
--
-- This file has been generated by hand (manually maintained)
--
-----------------------------------------------------------------------------

-- including the pic 16f877a
include 16f877a                       -- target PICmicro
-- XTAL at 20 MHz in pins OSC1 y OSC2, etc...
pragma target OSC HS                  -- XTAL
pragma target clock 20_000_000        -- 20 Mhz
pragma target WDT  disabled           -- WDT off
pragma target LVP  enabled            -- allow low voltage programming
-- ALL DIGITAL
enable_digital_io()                   -- disable analog I/O (if any)

-- The dds lib use a kind of SPI, but we generate all the comm code to
-- make it smaller
-- We assume that the DDS is connected as this
alias dds_sfqud_pin     is pin_B7       -- FREQ UPDATE PIN
alias dds_sclk_pin      is pin_B6       -- CLOCK PIN
alias dds_sdata_pin     is pin_B5       -- DATA PIN
-- No reset pin is used, but you can implement it, it's easy..

-- dds pind direction
pin_B7_direction = output
pin_B6_direction = output
pin_B5_direction = output
-- include and init the dds
include dds_ad9850                      -- load the dds lib
dds_init()                       -- this puts the dds to sleep

-- include delay for timing
include delay

-- VARS et all
-- freq limits
const dword FRQMIN      = 550000       -- 550Khz in hertz
const dword FRQMAX      = 1700000         -- 1.7Mhz in hertz
-- array steps
var      word  steps[2] = {10000, 1000}      -- 100Khz & 1Khz
-- var for actual frequency
var      dword VFO
-- for alternate the step
var      bit      alt         = 0

-- set VFO at min freq
VFO = FRQMIN

-- lets do some noise...
forever loop
   -- send freq to the DDS
   dds_frequency(VFO)
   -- wait for 500ms
   delay_100ms(5)
   -- increment the freq by step
   VFO = VFO + steps[byte(alt)]
   -- check boundary
   if (VFO == FRQMAX) then
      -- I'm at freq max
      -- reset to FRQMIN
      VFO = FRQMIN
      -- change step
      alt = !alt
   end if
end loop

Generated by JALlib CHM Help System | Source: dds_ad9833.jal


dds_init - JALlib Procedures Help

dds_init JALLIB PROCEDURE

Signature

PROCEDURE dds_init() IS

Description

inicializar los pines del DDS y el DDS como tal

Include

To use this procedure, include the library:

include dds_ad9850

Parameters

None

Return Value

None

Example

From sample file: 16f877a_dds_ad9850.jal

-- -----------------------------------------------------------------------------
-- Title: sample program for the dds_ad9850 library
-- Author: Pavel Milanes Costa, Copyright (c) 2013, all rights reserved.
--         Email: co7wt@frcuba.co.cu
--
-- Adapted-by:
--
-- Compiler:  >=2.4l
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    A sample file for the dds_ad9850 library, it's purpose is to sweep the RF
--    spectrum for the AM band (550Khz to 1.7Mhz) in increments of 10Khz, and
--    1Khz in an alternating loop
-- .
--    First sweep from 550Khz to 1.7 Mhz in 10 Khz steps
--    Second sweep from  550Khz to 1.7 Mhz in 1 Khz steps
--    repeat Frist.. Second.. etc...
-- .
--    In every step remains 500ms on freq
-- .
--    You can set your own sweep interval, steps and timings, see code
--
-- This file has been generated by hand (manually maintained)
--
-----------------------------------------------------------------------------

-- including the pic 16f877a
include 16f877a                       -- target PICmicro
-- XTAL at 20 MHz in pins OSC1 y OSC2, etc...
pragma target OSC HS                  -- XTAL
pragma target clock 20_000_000        -- 20 Mhz
pragma target WDT  disabled           -- WDT off
pragma target LVP  enabled            -- allow low voltage programming
-- ALL DIGITAL
enable_digital_io()                   -- disable analog I/O (if any)

-- The dds lib use a kind of SPI, but we generate all the comm code to
-- make it smaller
-- We assume that the DDS is connected as this
alias dds_sfqud_pin     is pin_B7       -- FREQ UPDATE PIN
alias dds_sclk_pin      is pin_B6       -- CLOCK PIN
alias dds_sdata_pin     is pin_B5       -- DATA PIN
-- No reset pin is used, but you can implement it, it's easy..

-- dds pind direction
pin_B7_direction = output
pin_B6_direction = output
pin_B5_direction = output
-- include and init the dds
include dds_ad9850                      -- load the dds lib
dds_init()                       -- this puts the dds to sleep

-- include delay for timing
include delay

-- VARS et all
-- freq limits
const dword FRQMIN      = 550000       -- 550Khz in hertz
const dword FRQMAX      = 1700000         -- 1.7Mhz in hertz
-- array steps
var      word  steps[2] = {10000, 1000}      -- 100Khz & 1Khz
-- var for actual frequency
var      dword VFO
-- for alternate the step
var      bit      alt         = 0

-- set VFO at min freq
VFO = FRQMIN

-- lets do some noise...
forever loop
   -- send freq to the DDS
   dds_frequency(VFO)
   -- wait for 500ms
   delay_100ms(5)
   -- increment the freq by step
   VFO = VFO + steps[byte(alt)]
   -- check boundary
   if (VFO == FRQMAX) then
      -- I'm at freq max
      -- reset to FRQMIN
      VFO = FRQMIN
      -- change step
      alt = !alt
   end if
end loop

Generated by JALlib CHM Help System | Source: dds_ad9850.jal


dds_reset - JALlib Procedures Help

dds_reset JALLIB PROCEDURE

Signature

PROCEDURE dds_reset() IS

Description

PUBLIC ----------------------------------------------------------------------
resets the dds chip and prepares it for operation. In will start in 'sleep' mode.

Include

To use this procedure, include the library:

include dds_ad9833

Parameters

None

Return Value

None

Example

From sample file: 16f628_dds_ad9833.jal

-- ------------------------------------------------------
-- Title: Sample the AD9833 dds chip with the Microchip pic16f628
--
-- Author: Tijs van Roon@RedSam, Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Control an Analog Devices AD9833 Digital Direct Synthesis chip with a Microchip PIC16f628.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 16 Okt 2010 23:30
--
-- ------------------------------------------------------
--
include 16f628                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS              -- HS crystal or resonator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  enabled         -- allow Low Voltage Programming
pragma target MCLR external        -- reset externally
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
include delay

enable_digital_io()                -- make all pins digital I/O
--
-- Specify the pin to which the AD9833 is connected
pin_A4_direction = output
pin_B7_direction = output
pin_B5_direction = output
alias dds_fsync_pin is pin_A4
alias dds_sclk_pin  is pin_B7
alias dds_sdata_pin is pin_B5

-- Include the DDS lib
include dds_ad9833

-- Reset the DDS chip.
dds_reset()

-- Initial frequency
var dword freq = 1000 -- 1 Khz

-- Loop
forever loop
   dds_frequency(freq)

   -- output triangle (Vpp = 0.6 V)
   dds_triangle()

   delay_1ms(250)

   -- output sine (Vpp = 0.6 V)
   dds_sine()

   delay_1ms(250)

   -- output square (Vpp >> 0.6 V)
   dds_square()

   delay_1ms(250)

   freq = freq + 1000
end loop

--

Generated by JALlib CHM Help System | Source: dds_ad9833.jal


dds_sine - JALlib Procedures Help

dds_sine JALLIB PROCEDURE

Signature

PROCEDURE dds_sine() IS

Description

Puts the device into sine mode. The device uses the lookup table to output a sine wave.

Include

To use this procedure, include the library:

include dds_ad9833

Parameters

None

Return Value

None

Example

From sample file: 16f628_dds_ad9833.jal

-- ------------------------------------------------------
-- Title: Sample the AD9833 dds chip with the Microchip pic16f628
--
-- Author: Tijs van Roon@RedSam, Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Control an Analog Devices AD9833 Digital Direct Synthesis chip with a Microchip PIC16f628.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 16 Okt 2010 23:30
--
-- ------------------------------------------------------
--
include 16f628                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS              -- HS crystal or resonator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  enabled         -- allow Low Voltage Programming
pragma target MCLR external        -- reset externally
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
include delay

enable_digital_io()                -- make all pins digital I/O
--
-- Specify the pin to which the AD9833 is connected
pin_A4_direction = output
pin_B7_direction = output
pin_B5_direction = output
alias dds_fsync_pin is pin_A4
alias dds_sclk_pin  is pin_B7
alias dds_sdata_pin is pin_B5

-- Include the DDS lib
include dds_ad9833

-- Reset the DDS chip.
dds_reset()

-- Initial frequency
var dword freq = 1000 -- 1 Khz

-- Loop
forever loop
   dds_frequency(freq)

   -- output triangle (Vpp = 0.6 V)
   dds_triangle()

   delay_1ms(250)

   -- output sine (Vpp = 0.6 V)
   dds_sine()

   delay_1ms(250)

   -- output square (Vpp >> 0.6 V)
   dds_square()

   delay_1ms(250)

   freq = freq + 1000
end loop

--

Generated by JALlib CHM Help System | Source: dds_ad9833.jal


dds_square - JALlib Procedures Help

dds_square JALLIB PROCEDURE

Signature

PROCEDURE dds_square() IS

Description

Puts the device into MSB-mode. The device outputs the value of the MSB bit of the
phase accumulator. Note that this output is not generated by the DAC and the Vpp is
more than the 0.6V of the other modes which do use the DAC.
The DAC is put to sleep in this mode.

Include

To use this procedure, include the library:

include dds_ad9833

Parameters

None

Return Value

None

Example

From sample file: 16f628_dds_ad9833.jal

-- ------------------------------------------------------
-- Title: Sample the AD9833 dds chip with the Microchip pic16f628
--
-- Author: Tijs van Roon@RedSam, Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Control an Analog Devices AD9833 Digital Direct Synthesis chip with a Microchip PIC16f628.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 16 Okt 2010 23:30
--
-- ------------------------------------------------------
--
include 16f628                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS              -- HS crystal or resonator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  enabled         -- allow Low Voltage Programming
pragma target MCLR external        -- reset externally
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
include delay

enable_digital_io()                -- make all pins digital I/O
--
-- Specify the pin to which the AD9833 is connected
pin_A4_direction = output
pin_B7_direction = output
pin_B5_direction = output
alias dds_fsync_pin is pin_A4
alias dds_sclk_pin  is pin_B7
alias dds_sdata_pin is pin_B5

-- Include the DDS lib
include dds_ad9833

-- Reset the DDS chip.
dds_reset()

-- Initial frequency
var dword freq = 1000 -- 1 Khz

-- Loop
forever loop
   dds_frequency(freq)

   -- output triangle (Vpp = 0.6 V)
   dds_triangle()

   delay_1ms(250)

   -- output sine (Vpp = 0.6 V)
   dds_sine()

   delay_1ms(250)

   -- output square (Vpp >> 0.6 V)
   dds_square()

   delay_1ms(250)

   freq = freq + 1000
end loop

--

Generated by JALlib CHM Help System | Source: dds_ad9833.jal


dds_triangle - JALlib Procedures Help

dds_triangle JALLIB PROCEDURE

Signature

PROCEDURE dds_triangle() IS

Description

Puts the device into triangle mode. The device uses the phase accumulator to derive
the DAC value.

Include

To use this procedure, include the library:

include dds_ad9833

Parameters

None

Return Value

None

Example

From sample file: 16f628_dds_ad9833.jal

-- ------------------------------------------------------
-- Title: Sample the AD9833 dds chip with the Microchip pic16f628
--
-- Author: Tijs van Roon@RedSam, Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Control an Analog Devices AD9833 Digital Direct Synthesis chip with a Microchip PIC16f628.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 16 Okt 2010 23:30
--
-- ------------------------------------------------------
--
include 16f628                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS              -- HS crystal or resonator
pragma target WDT  disabled        -- no watchdog
pragma target LVP  enabled         -- allow Low Voltage Programming
pragma target MCLR external        -- reset externally
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
include delay

enable_digital_io()                -- make all pins digital I/O
--
-- Specify the pin to which the AD9833 is connected
pin_A4_direction = output
pin_B7_direction = output
pin_B5_direction = output
alias dds_fsync_pin is pin_A4
alias dds_sclk_pin  is pin_B7
alias dds_sdata_pin is pin_B5

-- Include the DDS lib
include dds_ad9833

-- Reset the DDS chip.
dds_reset()

-- Initial frequency
var dword freq = 1000 -- 1 Khz

-- Loop
forever loop
   dds_frequency(freq)

   -- output triangle (Vpp = 0.6 V)
   dds_triangle()

   delay_1ms(250)

   -- output sine (Vpp = 0.6 V)
   dds_sine()

   delay_1ms(250)

   -- output square (Vpp >> 0.6 V)
   dds_square()

   delay_1ms(250)

   freq = freq + 1000
end loop

--

Generated by JALlib CHM Help System | Source: dds_ad9833.jal


debounce - JALlib Procedures Help

debounce JALLIB FUNCTION

Signature

function debounce(bit in polled, word in out state) return byte is

Description

The real meat of the system...

Include

To use this procedure, include the library:

include debounce

Parameters

  • polled - bit in
  • state - word in out

Return Value

byte - Function return value

Example

From sample file: 16f877_debounce.jal

-- ------------------------------------------------------
-- Title: debounce test
--
-- Author: Alun Jones, Copyright (c) 2012..2014, all rights reserved.
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program for the debounce library.
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_debounce.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction
;@jallib section button
-- button IO definition
alias button             is pin_c0
alias button_direction   is pin_c0_direction

enable_digital_io()

include delay
include debounce

led_direction = output
button_direction = input

-- Initialise the debounce state, requiring 100 samples
-- of a stable state before the debouncer will switch
-- in response.
var word state = debounce_init(100)

forever loop
   -- debounce will return 2 at the point where the button
   -- has pressed (assuming it's wired to ground) and held stable
   -- for 100 samples. In this case, with a 1000us delay in the loop,
   -- that's after around 0.1 seconds.
   --
   -- You could also use debounce_fast(button, state) here, in which
   -- case it will switch immediately after the button is pressed, but
   -- will be more sensitive to noise (not an issue where the button is
   -- a switch, but if it's a thresholded analogue signal with noise, this
   -- might not be what you want).
   if (debounce(button, state) == 2) then
      -- Toggle the LED.
      led = !led
   end if

   _usec_delay(1000)
end loop

Generated by JALlib CHM Help System | Source: debounce.jal


debounce.jal - JALLIB Library Documentation

debounce.jal JALLIB LIBRARY

Title

Generic debouncer.

Author

Alun Jones, Copyright (c) 2012..2012, all rights reserved.

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides a simple switch debounce function.
.
Quite often, when monitoring the state of a mechanical switch, it is
necessary to take switch bounce into consideration. Rather than going
straight from one stable state to another, it can take a significant
period during which the contacts of the switch bounce together. If
you don't take this into consideration then, rather than receiving
a single pulse, your sofware can end up seeing a sequence of many
pulses.
.
In an ideal world without switch bounce, perhaps you'd like to have the
following:
.
forever loop
if (pin_a0 == true) then
-- do some stuff
end if
-- do some other stuff
end loop
.
This library tries to make it possible to do this while handling
switch bounce for you. At its simplest, you could do the following:
.
var word state = debounce_init(200)
forever loop
if (debounce(pin_a0, state) == 1) then
-- do some stuff
end if
-- do some other stuff
end loop
.
In the example above, the lowest bit returned by the debounce function
will only flip after pin_a0's state has been polled in a stable state
200 times in a row. Choosing the threshold (200 in this case) is probably
matter of trial and error - it'll depend on the characteristics of the
switch you're using and how quickly your polling loop runs.
.
You must allocate a word to hold the bounce state, threshold and counter,
and initialise it using debounce_init (as above). The maximum threshold
value you can specify is 255, and the value is only stored with a
resolution of 6 bits. All threshold values are ORed with 0b11, so
specifying a threshold value of 9, for example, will give an actual
threshold value of 11. This may sound a bit odd, but it's so the bottom 2
bits of the status word can be stolen and used for storing internal
state. The actual counter uses the full 8 bits.
.
The debounce function also returns a second bit, which is set only when
the returned state has just changed. This is useful if you want something
to happen just once when a button is pressed, for example.
.
if (debounce(pin_a0, state) == 3) then
-- do some stuff
end if
.
The returned values are as follows then:
.
0b00 = 0 - Input is stable at 0 and has not just changed
0b01 = 1 - Input is stable at 1 and has not just changed
0b10 = 2 - Input is stable at 0 and has just changed from 1
0b11 = 3 - Input it stable at 1 and has just changed from 0
.
Here is a full list of all functions:
.
function debounce_init(byte in threshold) return word
.
This is used to initialise a state variable ready for use.
threshold is the number of calls after which the debounce
function should consider a new state stable.
.
function debounce(bit in polled, word in out state) return byte
.
This is the main function - I'm not going to go into detail here as
it's described above.
.
function debounce_fast(bit in polled, word in out state) return byte
.
You may have noticed that debounce() imposes a lag while it decides
whether the new state is stable. If it's critical that you respond
immediately to a state change, you can use debounce_fast instead. This
one is used in exactly the same way as debounce(), but rather than
waiting for a stable state, it assumes that a changed state is going
to stabilise to that changed state. So it flips its return value
immediately on detecting a state change. Then, it embargoes further
state changes until the threshold period has passed.
.
The downside of this is that if your input data sometimes receives
spurious short pulses that you'd like to ignore, debounce_fast will
act on them, turning them into longer pulses.
.
function debounce_state(word in state) return byte
.
This returns the last value that was returned by debounce for this
state variable.

Routines

  • debounce - Function returns byte
  • debounce_fast - Function returns byte
  • debounce_init - Function returns word
  • debounce_just_changed - Function returns bit
  • debounce_stable_state - Function returns bit
  • debounce_state - Function returns byte
  • debounce_threshold - Function returns byte
  • debounce_threshold - Function returns byte


debounce_fast - JALlib Procedures Help

debounce_fast JALLIB FUNCTION

Signature

function debounce_fast(bit in polled, word in out state) return byte is

Description

This one flips immediately on a state change, but ignores
subsequent state changes for the counter period. Useful
if you have to respond quickly and you know that an initial
state change will always stabilise eventually.

Include

To use this procedure, include the library:

include debounce

Parameters

  • polled - bit in
  • state - word in out

Return Value

byte - Function return value

Example

From sample file: 16f877_debounce.jal

-- ------------------------------------------------------
-- Title: debounce test
--
-- Author: Alun Jones, Copyright (c) 2012..2014, all rights reserved.
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program for the debounce library.
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_debounce.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction
;@jallib section button
-- button IO definition
alias button             is pin_c0
alias button_direction   is pin_c0_direction

enable_digital_io()

include delay
include debounce

led_direction = output
button_direction = input

-- Initialise the debounce state, requiring 100 samples
-- of a stable state before the debouncer will switch
-- in response.
var word state = debounce_init(100)

forever loop
   -- debounce will return 2 at the point where the button
   -- has pressed (assuming it's wired to ground) and held stable
   -- for 100 samples. In this case, with a 1000us delay in the loop,
   -- that's after around 0.1 seconds.
   --
   -- You could also use debounce_fast(button, state) here, in which
   -- case it will switch immediately after the button is pressed, but
   -- will be more sensitive to noise (not an issue where the button is
   -- a switch, but if it's a thresholded analogue signal with noise, this
   -- might not be what you want).
   if (debounce(button, state) == 2) then
      -- Toggle the LED.
      led = !led
   end if

   _usec_delay(1000)
end loop

Generated by JALlib CHM Help System | Source: debounce.jal


debounce_init - JALlib Procedures Help

debounce_init JALLIB FUNCTION

Signature

function debounce_init(byte in threshold) return word is

Description

Initialise. Set the threshold and the counter.

Include

To use this procedure, include the library:

include debounce

Parameters

  • threshold - byte in

Return Value

word - Function return value

Example

From sample file: 16f877_debounce.jal

-- ------------------------------------------------------
-- Title: debounce test
--
-- Author: Alun Jones, Copyright (c) 2012..2014, all rights reserved.
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program for the debounce library.
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_debounce.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction
;@jallib section button
-- button IO definition
alias button             is pin_c0
alias button_direction   is pin_c0_direction

enable_digital_io()

include delay
include debounce

led_direction = output
button_direction = input

-- Initialise the debounce state, requiring 100 samples
-- of a stable state before the debouncer will switch
-- in response.
var word state = debounce_init(100)

forever loop
   -- debounce will return 2 at the point where the button
   -- has pressed (assuming it's wired to ground) and held stable
   -- for 100 samples. In this case, with a 1000us delay in the loop,
   -- that's after around 0.1 seconds.
   --
   -- You could also use debounce_fast(button, state) here, in which
   -- case it will switch immediately after the button is pressed, but
   -- will be more sensitive to noise (not an issue where the button is
   -- a switch, but if it's a thresholded analogue signal with noise, this
   -- might not be what you want).
   if (debounce(button, state) == 2) then
      -- Toggle the LED.
      led = !led
   end if

   _usec_delay(1000)
end loop

Generated by JALlib CHM Help System | Source: debounce.jal


debug.jal - JALLIB Library Documentation

debug.jal JALLIB LIBRARY

Title

Debug via print library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

The debug library has all the same functions as the print library,
but the user defines constants to turn on and off this
library and users debug levels.

Sources

The jallib print library

Constants and Variables

debug_bits - var word = 0

Routines

  • debug_bit_10 - Procedure
  • debug_bit_highlow - Procedure
  • debug_bit_truefalse - Procedure
  • debug_byte_binary - Procedure
  • debug_byte_dec - Procedure
  • debug_byte_hex - Procedure
  • debug_char - Procedure
  • debug_crlf - Procedure
  • debug_dword_binary - Procedure
  • debug_dword_dec - Procedure
  • debug_dword_hex - Procedure
  • debug_nibble_binary - Procedure
  • debug_sbyte_dec - Procedure
  • debug_sdword_dec - Procedure
  • debug_sdword_hex - Procedure
  • debug_string - Procedure
  • debug_sword_dec - Procedure
  • debug_word_binary - Procedure
  • debug_word_dec - Procedure
  • debug_word_hex - Procedure


debug_byte_dec - JALlib Procedures Help

debug_byte_dec JALLIB PROCEDURE

Signature

procedure debug_byte_dec(word in debug_level,byte in data) is

Description

No description available.

Include

To use this procedure, include the library:

include debug

Parameters

  • debug_level - word in
  • data - byte in

Return Value

None

Example

From sample file: 18f2520_debug.jal

-- Title: Test program for Debug
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Debug sample. The debug library has all the same functions
--              as the print library, but the user defines constants to turn on
--              and off this library and users debug levels.
--
-- Sources:
-- The jallib print library
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_debug.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog
;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_1 = ON
debug_lvl_2 = OFF
debug_lvl_3 = ON

-- we are alive!
for 10 loop
   serial_hw_data = "!"
end loop

var byte step = 0
forever loop
   -- Debug level 0
   const byte str1[] = "The loop has begun!"
   debug_string(1,str1)
   debug_crlf(1)

   -- Debug level 1
   debug_dword_dec(2,70_000)
   step = step + 1
   debug_crlf(2)

   -- Debug level 2
   debug_byte_dec(3,step)
   debug_crlf(3)

   -- delay 1 sec
   _usec_delay(500_000)
end loop

Generated by JALlib CHM Help System | Source: debug.jal


debug_crlf - JALlib Procedures Help

debug_crlf JALLIB PROCEDURE

Signature

procedure debug_crlf(word in debug_level) is

Description

No description available.

Include

To use this procedure, include the library:

include debug

Parameters

  • debug_level - word in

Return Value

None

Example

From sample file: 18f2520_debug.jal

-- Title: Test program for Debug
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Debug sample. The debug library has all the same functions
--              as the print library, but the user defines constants to turn on
--              and off this library and users debug levels.
--
-- Sources:
-- The jallib print library
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_debug.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog
;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_1 = ON
debug_lvl_2 = OFF
debug_lvl_3 = ON

-- we are alive!
for 10 loop
   serial_hw_data = "!"
end loop

var byte step = 0
forever loop
   -- Debug level 0
   const byte str1[] = "The loop has begun!"
   debug_string(1,str1)
   debug_crlf(1)

   -- Debug level 1
   debug_dword_dec(2,70_000)
   step = step + 1
   debug_crlf(2)

   -- Debug level 2
   debug_byte_dec(3,step)
   debug_crlf(3)

   -- delay 1 sec
   _usec_delay(500_000)
end loop

Generated by JALlib CHM Help System | Source: debug.jal


debug_dword_dec - JALlib Procedures Help

debug_dword_dec JALLIB PROCEDURE

Signature

procedure debug_dword_dec(word in debug_level,dword in data) is

Description

No description available.

Include

To use this procedure, include the library:

include debug

Parameters

  • debug_level - word in
  • data - dword in

Return Value

None

Example

From sample file: 18f2520_debug.jal

-- Title: Test program for Debug
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Debug sample. The debug library has all the same functions
--              as the print library, but the user defines constants to turn on
--              and off this library and users debug levels.
--
-- Sources:
-- The jallib print library
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_debug.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog
;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_1 = ON
debug_lvl_2 = OFF
debug_lvl_3 = ON

-- we are alive!
for 10 loop
   serial_hw_data = "!"
end loop

var byte step = 0
forever loop
   -- Debug level 0
   const byte str1[] = "The loop has begun!"
   debug_string(1,str1)
   debug_crlf(1)

   -- Debug level 1
   debug_dword_dec(2,70_000)
   step = step + 1
   debug_crlf(2)

   -- Debug level 2
   debug_byte_dec(3,step)
   debug_crlf(3)

   -- delay 1 sec
   _usec_delay(500_000)
end loop

Generated by JALlib CHM Help System | Source: debug.jal


debug_queue.jal - JALLIB Library Documentation

debug_queue.jal JALLIB LIBRARY

Title

Debug Queue

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

A Queue to delay sending of debug data. Some libraries are
time sensitive (such as USB). Sending large amounts of debug
data at the same time can cause too much delay for the
device waiting.

Notes

This lib uses TIMER3 (a 16 bit timer)
Example:
alias debug_queue_out is serial_data -- output data to serial port
const byte DEBUG_QUEUE_SIZE = 254 -- queue holds 254 bytes (the maximum)
const byte DEBUG_QUEUE_AMOUNT = 1 -- Output 1 byte(s) max
const word DEBUG_QUEUE_FREQ = 100 -- look for output data at 100hz (every .01 ms)
const byte DEBUG_QUEUE_INTERRUPT = TRUE -- USE the interrupt routine.
include debug_queue
debug_queue_init()
print_string(debug_queue,"Debug Queue is Ready")
debug_queue = "."
print_crlf(debug_queue)

Include the queue lib

Constants and Variables

timer_interval - var word

Routines

  • debug_queue_calc_freq - Function returns word
  • debug_queue_init - Procedure
  • debug_queue_isr - Procedure
  • debug_queue_poll - Procedure
  • debug_queue_write - Procedure


debug_queue_init - JALlib Procedures Help

debug_queue_init JALLIB PROCEDURE

Signature

procedure debug_queue_init() is

Description

Initalize the debug_queue lib.

Include

To use this procedure, include the library:

include debug_queue

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_debug_queue.jal

-- Title: Debug Queue Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: A Queue to delay sending of debug data. Some libraries are
--              time sensitive (such as USB). Sending large amounts of debug
--              data at the same time can cause too much delay for the
--              device waiting.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--      The lib uses TIMER3 (a 16 bit timer)
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- Serial port is slow, using debug queue ensures our debug data doesn't
-- slow USB requests too much.
alias debug_queue_out is serial_data -- output debug data to serial port
const byte DEBUG_QUEUE_SIZE = 254    -- queue holds 254 bytes (the maximum)
const byte DEBUG_QUEUE_AMOUNT = 1    -- Output 1 byte(s) max
const word DEBUG_QUEUE_FREQ = 100    -- look for output data at 100hz (every .01 ms)
const byte DEBUG_QUEUE_INTERRUPT = TRUE -- USE the interrupt routine.
include debug_queue
debug_queue_init()
alias serial_data_debug is debug_queue
--
print_string(debug_queue,"Debug Queue is Ready")
print_crlf(debug_queue)

-- main program
forever loop
   debug_queue = "."
   delay_1ms(200)
end loop

Generated by JALlib CHM Help System | Source: debug_queue.jal


debug_string - JALlib Procedures Help

debug_string JALLIB PROCEDURE

Signature

procedure debug_string(word in debug_level,byte in str_in[]) is

Description

No description available.

Include

To use this procedure, include the library:

include debug

Parameters

  • debug_level - word in
  • str_in[] - byte in

Return Value

None

Example

From sample file: 18f2520_debug.jal

-- Title: Test program for Debug
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Debug sample. The debug library has all the same functions
--              as the print library, but the user defines constants to turn on
--              and off this library and users debug levels.
--
-- Sources:
-- The jallib print library
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_debug.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog
;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_1 = ON
debug_lvl_2 = OFF
debug_lvl_3 = ON

-- we are alive!
for 10 loop
   serial_hw_data = "!"
end loop

var byte step = 0
forever loop
   -- Debug level 0
   const byte str1[] = "The loop has begun!"
   debug_string(1,str1)
   debug_crlf(1)

   -- Debug level 1
   debug_dword_dec(2,70_000)
   step = step + 1
   debug_crlf(2)

   -- Debug level 2
   debug_byte_dec(3,step)
   debug_crlf(3)

   -- delay 1 sec
   _usec_delay(500_000)
end loop

Generated by JALlib CHM Help System | Source: debug.jal


delay.jal - JALLIB Library Documentation

delay.jal JALLIB LIBRARY

Title

Delays procedures at any processor frequency

Author

Stef Mientki, Copyright (c) 2002..2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Joep Suijs

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library for delays at any processor frequency.
It's based on the JAL v2 compiler generator _usec_delay.
Fixed delays for the short intervals:
delay_1us(), delay_2us(), delay_3us(), delay_4us(), delay_5us(),
delay_6us(), delay_7us(), delay_8us(), delay_9us()
These procedures are 'inline' and are as accurate as the ocillator source.
For the longer delays, procedure with parameter N ( 1.. 255)
delay_10us(n)
delay_1ms(n)
delay_100ms(n)
These procedures are due to call/return overhead slightly clock
frequency dependent.

fixed delay of 1 usec (no arguments)

Routines

  • delay_100ms - Procedure
  • delay_10us - Procedure
  • delay_1ms - Procedure
  • delay_1s - Procedure
  • delay_1us - Procedure
  • delay_2us - Procedure
  • delay_3us - Procedure
  • delay_4us - Procedure
  • delay_5us - Procedure
  • delay_6us - Procedure
  • delay_7us - Procedure
  • delay_8us - Procedure
  • delay_9us - Procedure


delay_1ms - JALlib Procedures Help

delay_1ms JALLIB PROCEDURE

Signature

procedure delay_1ms(word in n) is

Description

Delays for n * 1 msec

Include

To use this procedure, include the library:

include delay

Parameters

  • n - word in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: delay.jal


delay_1s - JALlib Procedures Help

delay_1s JALLIB PROCEDURE

Signature

procedure delay_1s(word in n) is

Description

Delays for n * 1 sec

Include

To use this procedure, include the library:

include delay

Parameters

  • n - word in

Return Value

None

Example

From sample file: 18f2520_print_large_number.jal

-- ------------------------------------------------------
-- Title:  test file for printing large numbers
--
-- Author: Oliver "Kiste" Seitz
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Demo program for print.jal library using Microchip PIC12f615.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_print_large_number.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog

enable_digital_io()                -- make all pins digital I/O

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

serial_hw_init()

alias serial_data is serial_hw_data

const VAR_SIZE=32       -- set the maximum variable size

const PRINT_MAX_VAR_SIZE=VAR_SIZE   -- use this size also for print.jal

include print

include delay

delay_1s(5)          -- some seconds initial delay to move eyes from power plug to computer screen ;-)

var byte*VAR_SIZE runner      -- this variable holds the results of the computations

var byte*VAR_SIZE carry       -- some auxiliary variable

var word counter

var bit overflow

const byte title11[]="The largest printable number=\r\n2^"

print_string(serial_data,title11)

print_word_dec(serial_data,8*VAR_SIZE)

serial_data="-"
serial_data="1"
serial_data="="

runner=0
runner=runner-1

print_maxvar_dec(serial_data,runner)
print_crlf(serial_data)
print_crlf(serial_data)

overflow=false
runner=1
counter=0

const byte title1[]="Factorials:"
print_string(serial_data,title1) -- print a nice header
print_crlf(serial_data)

repeat

  print_word_dec(serial_data,counter)
  serial_data="!"
  serial_data="="
  print_maxvar_dec(serial_data,runner)
  print_crlf(serial_data)

         -- 0! = 1 ; n! = (n-1)! * n
         -- We do not use multiplication here, as it uses way more ram than additions.
         -- Besides, overflow detection is easy and cheap when only using additions.
         -- Execution time is no real problem, as the loop will not repeat very often,
         -- 70! (=2485 loop runs altogether) will already result in more than 100 decimal digits.

  carry=runner
  for counter loop
    runner=runner+carry
    if runner<=carry then
      overflow=true
    end if
  end loop
  counter=counter+1

until overflow

print_crlf(serial_data)

const byte title2[]="Powers of two:"
print_string(serial_data,title2) -- print a nice header
print_crlf(serial_data)

counter=0
runner=1

repeat
  serial_data="2"
  serial_data="^"
  print_word_dec(serial_data,counter)
  serial_data="="
  print_maxvar_dec(serial_data,runner)
  print_crlf(serial_data)

  counter=counter+1
  runner=runner<<1

until runner==0

const byte title3[]="That's it!"
print_string(serial_data,title3) -- say goodbye
print_crlf(serial_data)
print_crlf(serial_data)
delay_1ms(3)            -- wait for the last 2 bytes to be transmitted
asm sleep            -- switch off :-)

forever loop
end loop
--

Generated by JALlib CHM Help System | Source: delay.jal


delay_1us - JALlib Procedures Help

delay_1us JALLIB PROCEDURE

Signature

procedure delay_1us() is

Description

fixed delay of 1 usec (no arguments)

Include

To use this procedure, include the library:

include delay

Parameters

None

Return Value

None

Example

From sample file: 16f15325_stopwatch2.jal

-- -----------------------------------------------------------------------------
-- Title: Test program for Stopwatch2.
-- Author: Rob Jansen, Copyright (c) 2023..2023 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This example shows basic usage stopwatch2 library which can
--              be used to time events.
--
-- Sources:     This program is based on the stopwatch sample program created by
--              Matt Schinkel. It was created for testing - compiling - the update
--              of the stopwatch library for newer PIC types like the 16F15325.
--
-- Notes:       This sample program is created manually.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division

-- Enable weak pull up for all ports
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()   -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- Declaration of the USART1 pins
alias pin_RX_direction  is pin_C4_direction
alias pin_TX_direction  is pin_C5_direction

-- Re-assign the pins. Note: This must always be done to let it work
-- even for the default assignment.
include pps
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
pps_control_lock(TRUE)

-- setup uart for communication
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH2_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH2_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH2_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch2 -- include the library
--
stopwatch2_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch2_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch2_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch2_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch2 time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch2_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch2 instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2)

-- print the time unit of measurement
if STOPWATCH2_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

-- Give the serial port some time to send the last characters.
_usec_delay(100_000)

Generated by JALlib CHM Help System | Source: delay.jal


delay_10us - JALlib Procedures Help

delay_10us JALLIB PROCEDURE

Signature

procedure delay_10us(byte in n) is

Description

Delays for n * 10 usec

Include

To use this procedure, include the library:

include delay

Parameters

  • n - byte in

Return Value

None

Example

From sample file: 18f2550_usb_hid_mouse.jal

-- Title: USB HID device demo
-- Author: Albert Faber, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse pointing USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID is recognized by
-- the host operating systems, it will move around the mouse pointer
-- --
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: compiled with following flags
-- -loader18 -no-fuse
-- use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- ------------------------------------------------------
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_hid_mouse.jal
--

;@jallib section board_description

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

include delay

;@jallib section serial

-- whether or not using the serial port
const HAS_SERIAL_DEBUG_PORT = 1

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

  -- uncomment when directly coupled (i.e. without max 232) to rs-232C
  -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure
end if

const bit USB_DEBUG = false
const bit USB_DEBUG_HIGH = false
const bit USB_HID_DEBUG = false
const bit USB_HID_DEBUG_HIGH = false
const byte USB_HID_ENDPOINT = 0x01
var volatile bit usb_hid_can_tx = true

include usb_defs

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 8
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = 8
const word USB_EP1_IN_ADDR  = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )

var volatile byte  usb_ep1in_buf[ 8 ] at USB_EP1_IN_ADDR

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    0x08,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x00,
    0x00,		-- Mouse circle demo
    0x02,
    0x00, 	     -- version 2.0 of the product
    0x01,		-- string 1 for manufacturer
    0x02,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x09 + 0x07

const byte USB_HID_REPORT1[]=
{
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x02, -- Usage (Mouse)
    0xA1, 0x01, -- Collection (Application)
    0x09, 0x01, -- Usage (Pointer)
    0xA1, 0x00, -- Collection (Physical)
    0x05, 0x09, -- Usage Page (Buttons)
    0x19, 0x01, -- Usage Minimum (01)
    0x29, 0x03, -- Usage Maximum (03)
    0x15, 0x00, -- Logical Minimum (0)
    0x25, 0x01, -- Logical Maximum (0)
    0x95, 0x03, -- Report Count (3)
    0x75, 0x01, -- Report Size (1)
    0x81, 0x02, -- Input (Data, Variable, Absolute)
    0x95, 0x01, -- Report Count (1)
    0x75, 0x05, -- Report Size (5)
    0x81, 0x01, -- Input (Constant), 5 bit padding
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x30, -- Usage (X)
    0x09, 0x31, -- Usage (Y)
    0x15, 0x81, -- Logical Minimum (-127)
    0x25, 0x7F, -- Logical Maximum (127)
    0x75, 0x08, -- Report Size (8)
    0x95, 0x02, -- Report Count (2)
    0x81, 0x06, -- Input (Data, Variable, Relative)
    0xC0, 0xC0
}

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,	-- length,
    USB_DT_INTERFACE,	-- descriptor_type,
    0x00,	-- interface_number, (starts at zero)
    0x00,	-- alternate_setting, (no alternatives)
    0x01,	-- num_endpoints,
    0x03,	-- interface_class, (HID)
    0x01,	-- interface_subclass, (boot - is this necessary?)
    0x02,	-- interface_protocol, (mouse)
    0x00,	-- interface_string_id;

    -- hid descriptor - - - - - - - - - - - - - - -
    0x09,				-- length,
    USB_DT_HID,			-- descriptor_type;
    0x11,
    0x01,				-- hid_spec in BCD (1.11)
    0x00,				-- country_code, (0=not country specific)
    0x01,				-- num_class_descriptors, (1)
    USB_DT_HID_REPORT,	-- class_descriptor_type; (0x22 = report)
    (count( USB_HID_REPORT1 ) & 0xFF ),
    (count( USB_HID_REPORT1 ) >> 8 ),

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    0b00000011,			-- attributes; (Interrupt)
    0x03,
    0x00,				-- max_packet_size
    0x0A				-- interval (10ms)
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

const byte USB_STRING1[] =
{
    0x36,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "M", 0x00,
    "i", 0x00,
    "c", 0x00,
    "r", 0x00,
    "o", 0x00,
    "c", 0x00,
    "h", 0x00,
    "i", 0x00,
    "p", 0x00,
    " ", 0x00,
    "T", 0x00,
    "e", 0x00,
    "c", 0x00,
    "h", 0x00,
    "n", 0x00,
    "o", 0x00,
    "l", 0x00,
    "o", 0x00,
    "g", 0x00,
    "y", 0x00,
    ",", 0x00,
    " ", 0x00,
    "I", 0x00,
    "n", 0x00,
    "c", 0x00,
    ".", 0x00
}

const byte USB_STRING2[44] =
{
    44,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    " ", 0x00,
    "H", 0x00,
    "I", 0x00,
    "D", 0x00,
    " ", 0x00,
    "M", 0x00,
    "o", 0x00,
    "u", 0x00,
    "s", 0x00,
    "e", 0x00,
    " ", 0x00,
    "D", 0x00,
    "e", 0x00,
    "m", 0x00,
    "o", 0x00
}

include usb_drv_core

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte  in byte_count) is
    pragma inline
    if USB_HID_DEBUG_HIGH then
        const byte str[] = " EP data in: "
        const byte str1[] = " bytes "
        print_string( serial_hw_data,str )
        print_byte_hex( serial_hw_data, byte_count & 0xFF)
        print_string(serial_hw_data,str1)
    end if

    -- data has been sent, so do we need to send more?
    if (end_point == USB_HID_ENDPOINT) then
        -- it's the data end point
        usb_hid_can_tx = true
    end if
end procedure

include usb_drv

-- constants
const sbyte dir_table[] = {-4,-4,-4, 0, 4, 4, 4, 0}
const  byte str_welcome[] = "JALLIB USB HID MOUSE DEMO version 1.0\nplease wait (takes ~10 seconds) before the device it is fully configured"

-- variables
var word i = 0
var byte movement_length
var byte vector = 0
var bit usb_initialized = false
var byte data_buffer[3]
var word ticks100us = 0
var bit enable_mouse = false

procedure usb_tasks() is
    -- Servicing Hardware
    -- use polling method
    usb_handle_isr()
end procedure

-- interrupts? No thanks
while INTCON_GIE loop
    INTCON_GIE = false
end loop

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

-- setup the USB device
usb_setup()

-- enable USB device
usb_enable_module()

-- initialize HID buffer
data_buffer[0] = 0x00
data_buffer[1] = 0x00
data_buffer[2] = 0x00

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_tasks()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

        -- note user via serial line that USB has been configured
        if usb_initialized == false then
            usb_initialized = true

            if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                const  byte str[] = "USB device has been configured by the HOST!"
                print_string(serial_hw_data, str )
                serial_newline()
            end if
        end if

        -- now the mouse pointer can be moved around
        enable_mouse = true
    end if

    if enable_mouse then
        ticks100us = ticks100us + 1
        delay_10us(10)

        if ticks100us == 250 then
            ticks100us = 0

            if( movement_length > 16 ) then
                data_buffer[0] = 0
                data_buffer[1] = byte( dir_table[vector & 0x07] ) -- X-Vector
                data_buffer[2] = byte( dir_table[(vector+2) & 0x07] ) -- Y-Vector
                vector = vector+1
                movement_length = 0
            end if

            if 	( usb_hid_can_tx ) then
                usb_hid_can_tx = false
                usb_send_data(1, data_buffer, 3, low )
                movement_length =  movement_length + 1
            end if

        end if
    end if

    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
            serial_hw_write( RCREG )

            if RCREG == "S" then
            end if
            if RCREG == "T" then
            end if
        end if
    end if

end loop

Generated by JALlib CHM Help System | Source: delay.jal


delay_100ms - JALlib Procedures Help

delay_100ms JALLIB PROCEDURE

Signature

procedure delay_100ms(word in n) is

Description

Delays for n * 100 msec

Include

To use this procedure, include the library:

include delay

Parameters

  • n - word in

Return Value

None

Example

From sample file: 18f14k22_ws2812b_async.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with USART Asynchronous
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 18f14k22 with INTOSC at Fosc = 64 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 18f14k22

-- Internal oscillator at 16 MHz with PLL enabled -> 64 MHz
pragma target clock    64_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target PCLKEN   ENABLED            -- primary clock
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target IESO     DISABLED           -- no osc switchover
pragma target PWRTE    ENABLED            -- power up delay
pragma target BROWNOUT DISABLED           -- no brownout
pragma target WDT      CONTROL            -- watchdog software controlled
pragma target HFOFST   ENABLED            -- wait for stable osc
pragma target MCLR     EXTERNAL           -- reset externally
pragma target LVP      ENABLED            -- allow LVP
pragma target DEBUG    DISABLED           -- no debug

WDTCON_SWDTEN = DISABLED                  -- WDT disabled

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled

enable_digital_io()                       -- all pins digital

alias led is pin_A0                       -- being alive signal
pin_A0_direction = OUTPUT
led = ON

const WS2812B_NUM = 30

include ws2812b_async                     -- support library (USART ASYNC variant)
ws2812b_async_init()                      -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: delay.jal


dfplayer.jal - JALLIB Library Documentation

dfplayer.jal JALLIB LIBRARY

Title

Library for the DFPlayer Mini.

Author

Rob Jansen, Copyright (c) 2020..2020, all rights reserved., Adapted-by:

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

JAL library for use of the DFPlayer Mini.

Notes

The default serial interface of the DFPlayer Mini is 9600 baud,
1 stopbit, no parity and no flowcontrol.
At least one of the JAL serial libraries must be included and
initialized by the main program with these settings.
A read timeout is used for the DFPlayer to respond. This timeout is
can be set in steps of 100 us can be overruled by defining:
const word DFPLAYER_READ_TIMEOUT = 5_000 -- 0,5 seconds (default).
Some info on DFPlayer folders and audio files:
-) Audio files can be mp3 or wav format
-) Folders used must be named 01 to 99, ADVERT or MP3
-) Files are numbered 001 to 255 or 0001 to 3000 with extension .mp3 or .wav
-) Folders 01 to 15 can contain files named 001 to 255 and 0001 to 3000
these are the so called special 3000 track folders.
-) Folders 16 to 99 can contain files 001 to 255
-) Folder ADVERT can contain advertisement files named 0001 to 3000
-) Folder MP3 can contain mp3 only files named 0001 to 3000

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Maximum wait time to receive data from the DFPlayer. The read timeout can
be overruled by the main program. Timeout is in steps of 100 us.

Sources

Inspired by: https://github.com/PowerBroker2/DFPlayerMini_Fast

Constants and Variables

DFPLAYER_READ_TIMEOUT - const word = 5_000 -- 0,5 seconds (default).
0,5 seconds (default).
DFPLAYER_MAX_VOLUME - const byte = 30
DFPLAYER_EQUALIZER_NORMAL - const byte = 0
DFPLAYER_EQUALIZER_POP - const byte = 1
DFPLAYER_EQUALIZER_ROCK - const byte = 2
DFPLAYER_EQUALIZER_JAZZ - const byte = 3
DFPLAYER_EQUALIZER_CLASSIC - const byte = 4
DFPLAYER_EQUALIZER_BASE - const byte = 5
DFPLAYER_MODE_REPEAT - const byte = 0
DFPLAYER_MODE_FOLDER_REPEAT - const byte = 1
DFPLAYER_MODE_SINGLE_REPEAT - const byte = 2
DFPLAYER_MODE_RANDOM - const byte = 3
DFPLAYER_MODE_PLAY - const byte = 4
DFPLAYER_DEVICE_USB - const byte = 1
DFPLAYER_DEVICE_SD - const byte = 2
DFPLAYER_DEVICE_AUX - const byte = 3
DFPLAYER_DEVICE_SLEEP - const byte = 4
DFPLAYER_DEVICE_FLASH - const byte = 5
ok - var bit

Routines

  • _dfplayer_calculate_checksum - Function returns word
  • _dfplayer_flush_serial - Procedure
  • _dfplayer_get_byte - Function returns bit
  • _dfplayer_get_message - Function returns bit
  • _dfplayer_message_received - Function returns bit
  • _dfplayer_query - Function returns bit
  • _dfplayer_send_data - Procedure
  • dfplayer_dac_off - Procedure
  • dfplayer_dac_on - Procedure
  • dfplayer_decrement_volume - Procedure
  • dfplayer_get_current_flash_track - Function returns bit
  • dfplayer_get_current_sd_track - Function returns bit
  • dfplayer_get_current_usb_track - Function returns bit
  • dfplayer_get_equalizer - Function returns bit
  • dfplayer_get_mode - Function returns bit
  • dfplayer_get_nr_of_flash_tracks - Function returns bit
  • dfplayer_get_nr_of_folders - Function returns bit
  • dfplayer_get_nr_of_sd_tracks - Function returns bit
  • dfplayer_get_nr_of_tracks_in_folder - Function returns bit
  • dfplayer_get_nr_of_usb_tracks - Function returns bit
  • dfplayer_get_version - Function returns bit
  • dfplayer_get_volume - Function returns bit
  • dfplayer_increment_volume - Procedure
  • dfplayer_is_paused - Function returns bit
  • dfplayer_is_playing - Function returns bit
  • dfplayer_is_sleeping - Function returns bit
  • dfplayer_is_stopped - Function returns bit
  • dfplayer_normal_mode - Procedure
  • dfplayer_pause - Procedure
  • dfplayer_play - Procedure
  • dfplayer_play_3000_folder - Procedure
  • dfplayer_play_advertisement - Procedure
  • dfplayer_play_folder - Procedure
  • dfplayer_play_mp3_folder - Procedure
  • dfplayer_play_next - Procedure
  • dfplayer_play_previous - Procedure
  • dfplayer_play_random - Procedure
  • dfplayer_repeat_folder - Procedure
  • dfplayer_repeat_track - Procedure
  • dfplayer_reset - Procedure
  • dfplayer_resume - Procedure
  • dfplayer_set_equalizer - Procedure
  • dfplayer_set_playback_source - Procedure
  • dfplayer_set_volume - Procedure
  • dfplayer_sleep_mode - Procedure
  • dfplayer_start_repeat_current - Procedure
  • dfplayer_start_repeat_play - Procedure
  • dfplayer_stop - Procedure
  • dfplayer_stop_advertisement - Procedure
  • dfplayer_stop_repeat_current - Procedure
  • dfplayer_stop_repeat_play - Procedure


dfplayer_dac_off - JALlib Procedures Help

dfplayer_dac_off JALLIB PROCEDURE

Signature

procedure dfplayer_dac_off() is

Description

Switch the DAC off (is on by default).

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_dac_on - JALlib Procedures Help

dfplayer_dac_on JALLIB PROCEDURE

Signature

procedure dfplayer_dac_on() is

Description

Switch the DAC on (is on by default).

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_decrement_volume - JALlib Procedures Help

dfplayer_decrement_volume JALLIB PROCEDURE

Signature

procedure dfplayer_decrement_volume() is

Description

Decrement the volume of the DFPlayer.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_current_flash_track - JALlib Procedures Help

dfplayer_get_current_flash_track JALLIB FUNCTION

Signature

function dfplayer_get_current_flash_track(word out track) return bit is

Description

Return the current track on the Flash device of the DFPlayer. Function
returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_current_sd_track - JALlib Procedures Help

dfplayer_get_current_sd_track JALLIB FUNCTION

Signature

function dfplayer_get_current_sd_track(word out track) return bit is

Description

Return the current track on the SD device of the DFPlayer. Function returns
TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_current_usb_track - JALlib Procedures Help

dfplayer_get_current_usb_track JALLIB FUNCTION

Signature

function dfplayer_get_current_usb_track(word out track) return bit is

Description

Return the current track from the USB device of the DFPlayer. Function
returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_equalizer - JALlib Procedures Help

dfplayer_get_equalizer JALLIB FUNCTION

Signature

function dfplayer_get_equalizer(byte out equalizer) return bit is

Description

Return the current equalizer setting of the DFPlayer. Function returns TRUE
if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • equalizer - byte out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_mode - JALlib Procedures Help

dfplayer_get_mode JALLIB FUNCTION

Signature

function dfplayer_get_mode(byte out mode) return bit is

Description

Return the current mode setting of the DFPlayer. Function returns TRUE if
succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • mode - byte out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_nr_of_flash_tracks - JALlib Procedures Help

dfplayer_get_nr_of_flash_tracks JALLIB FUNCTION

Signature

function dfplayer_get_nr_of_flash_tracks(word out tracks) return bit is

Description

Return the numner of tracks on the Flash device of the DFPlayer. Note that the
track number returned is a count starting from the first folder. Function
returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • tracks - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_nr_of_folders - JALlib Procedures Help

dfplayer_get_nr_of_folders JALLIB FUNCTION

Signature

function dfplayer_get_nr_of_folders(word out nr_of_folders) return bit is

Description

Return the number of folders of the DFPlayer. Function returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • nr_of_folders - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_nr_of_sd_tracks - JALlib Procedures Help

dfplayer_get_nr_of_sd_tracks JALLIB FUNCTION

Signature

function dfplayer_get_nr_of_sd_tracks(word out tracks) return bit is

Description

Return the numner of tracks on the SD device of the DFPlayer. Note that the
track number returned is a count starting from the first folder. Function
returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • tracks - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_nr_of_tracks_in_folder - JALlib Procedures Help

dfplayer_get_nr_of_tracks_in_folder JALLIB FUNCTION

Signature

function dfplayer_get_nr_of_tracks_in_folder(word in folder,

Description

Return the number of tracks in the given folder of the DFPlayer. Function
returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_nr_of_usb_tracks - JALlib Procedures Help

dfplayer_get_nr_of_usb_tracks JALLIB FUNCTION

Signature

function dfplayer_get_nr_of_usb_tracks(word out tracks) return bit is

Description

Return the numner of tracks on the USB device of the DFPlayer.Note that the
track number returned is a count starting from the first folder. Function
returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • tracks - word out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_version - JALlib Procedures Help

dfplayer_get_version JALLIB FUNCTION

Signature

function dfplayer_get_version(byte out version) return bit is

Description

Return the current version of the DFPlayer. Function returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • version - byte out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_get_volume - JALlib Procedures Help

dfplayer_get_volume JALLIB FUNCTION

Signature

function dfplayer_get_volume(byte out volume) return bit is

Description

Return the current volume of the DFPlayer. Function returns TRUE if succesful.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • volume - byte out

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_increment_volume - JALlib Procedures Help

dfplayer_increment_volume JALLIB PROCEDURE

Signature

procedure dfplayer_increment_volume() is

Description

Increment the volume of the DFPlayer.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_is_paused - JALlib Procedures Help

dfplayer_is_paused JALLIB FUNCTION

Signature

function dfplayer_is_paused() return bit is

Description

Check if the DFPlayer is paused and return TRUE if so.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_is_playing - JALlib Procedures Help

dfplayer_is_playing JALLIB FUNCTION

Signature

function dfplayer_is_playing() return bit is

Description

Check if the DFPlayer is playing and return TRUE if so.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_is_sleeping - JALlib Procedures Help

dfplayer_is_sleeping JALLIB FUNCTION

Signature

function dfplayer_is_sleeping() return bit is

Description

Check if the DFPlayer is sleepting and return TRUE if so.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_is_stopped - JALlib Procedures Help

dfplayer_is_stopped JALLIB FUNCTION

Signature

function dfplayer_is_stopped() return bit is

Description

Check if the DFPlayer is stopped and return TRUE if so.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_normal_mode - JALlib Procedures Help

dfplayer_normal_mode JALLIB PROCEDURE

Signature

procedure dfplayer_normal_mode() is

Description

Put the DFPlayer in normal operation mode. This feature is not specified in
all data sheets and its operation is not defined.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_pause - JALlib Procedures Help

dfplayer_pause JALLIB PROCEDURE

Signature

procedure dfplayer_pause() is

Description

Pause the DFPlayer.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play - JALlib Procedures Help

dfplayer_play JALLIB PROCEDURE

Signature

procedure dfplayer_play(word in track_number) is

Description

Play the given track. The track number must be in range 1 to the number
returned by the function dfplayer_get_nr_of_..._tracks().

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track_number - word in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_3000_folder - JALlib Procedures Help

dfplayer_play_3000_folder JALLIB PROCEDURE

Signature

procedure dfplayer_play_3000_folder(byte in folder_number, word in track_number) is

Description

Play the given track in the special 3000 track given folder. Folder must
be in range 1 to 15 and track in range 0001 to 3000.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • folder_number - byte in
  • track_number - word in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_advertisement - JALlib Procedures Help

dfplayer_play_advertisement JALLIB PROCEDURE

Signature

procedure dfplayer_play_advertisement(word in track_number) is

Description

Play Advertisement.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track_number - word in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_folder - JALlib Procedures Help

dfplayer_play_folder JALLIB PROCEDURE

Signature

procedure dfplayer_play_folder(byte in folder_number, byte in track_number) is

Description

Play the given track in the given folder. Folder number in range 1 to 99,
track number in range 1 to 255.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • folder_number - byte in
  • track_number - byte in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_mp3_folder - JALlib Procedures Help

dfplayer_play_mp3_folder JALLIB PROCEDURE

Signature

procedure dfplayer_play_mp3_folder(word in track_number) is

Description

Play the given track from the MP3 folder. Track number in range 1 to 3000.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track_number - word in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_next - JALlib Procedures Help

dfplayer_play_next JALLIB PROCEDURE

Signature

procedure dfplayer_play_next() is

Description

Play the next track.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_previous - JALlib Procedures Help

dfplayer_play_previous JALLIB PROCEDURE

Signature

procedure dfplayer_play_previous() is

Description

Play the previous track.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_play_random - JALlib Procedures Help

dfplayer_play_random JALLIB PROCEDURE

Signature

procedure dfplayer_play_random() is

Description

Play random.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_repeat_folder - JALlib Procedures Help

dfplayer_repeat_folder JALLIB PROCEDURE

Signature

procedure dfplayer_repeat_folder(word in folder_number) is

Description

Set repeat of the given folder.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • folder_number - word in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_repeat_track - JALlib Procedures Help

dfplayer_repeat_track JALLIB PROCEDURE

Signature

procedure dfplayer_repeat_track(word in track_number) is

Description

Set repeat of the given track.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • track_number - word in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_reset - JALlib Procedures Help

dfplayer_reset JALLIB PROCEDURE

Signature

procedure dfplayer_reset() is

Description

Reset the DFPlayer and give the DFPlayer sufficient time to initialize.
Note that dfplayer_reset() and dfplayer_init() are the same.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_resume - JALlib Procedures Help

dfplayer_resume JALLIB PROCEDURE

Signature

procedure dfplayer_resume() is

Description

Resume playback of the DFPlayer.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_set_equalizer - JALlib Procedures Help

dfplayer_set_equalizer JALLIB PROCEDURE

Signature

procedure dfplayer_set_equalizer(byte in equalizer) is

Description

Set the equalizer of the DFPlayer. Parameter must be one of the equalizer modes.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • equalizer - byte in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_set_playback_source - JALlib Procedures Help

dfplayer_set_playback_source JALLIB PROCEDURE

Signature

procedure dfplayer_set_playback_source(byte in source) is

Description

Set the playback source.

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • source - byte in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_set_volume - JALlib Procedures Help

dfplayer_set_volume JALLIB PROCEDURE

Signature

procedure dfplayer_set_volume(byte in volume) is

Description

Set the volume of the DFPlayer. Must be in range 0 .. DFPLAYER_MAX_VOLUME

Include

To use this procedure, include the library:

include dfplayer

Parameters

  • volume - byte in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_sleep_mode - JALlib Procedures Help

dfplayer_sleep_mode JALLIB PROCEDURE

Signature

procedure dfplayer_sleep_mode() is

Description

Put the DFPlayer in sleep mode. Note the DFPlayer can only be re-activated
again by switching the power off and on again.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_start_repeat_current - JALlib Procedures Help

dfplayer_start_repeat_current JALLIB PROCEDURE

Signature

procedure dfplayer_start_repeat_current() is

Description

Start the repeat of the current track.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_stop - JALlib Procedures Help

dfplayer_stop JALLIB PROCEDURE

Signature

procedure dfplayer_stop() is

Description

Stop playing a track.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_stop_advertisement - JALlib Procedures Help

dfplayer_stop_advertisement JALLIB PROCEDURE

Signature

procedure dfplayer_stop_advertisement() is

Description

Stop playing Advertisement.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_stop_repeat_current - JALlib Procedures Help

dfplayer_stop_repeat_current JALLIB PROCEDURE

Signature

procedure dfplayer_stop_repeat_current() is

Description

Stop the repeat of the current track.

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dfplayer_stop_repeat_play - JALlib Procedures Help

dfplayer_stop_repeat_play JALLIB PROCEDURE

Signature

procedure dfplayer_stop_repeat_play() is

Description

Stop the repeat playback of all tracks

Include

To use this procedure, include the library:

include dfplayer

Parameters

None

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: dfplayer.jal


dht11_read - JALlib Procedures Help

dht11_read JALLIB FUNCTION

Signature

function dht11_read() return byte is

Description

Read temperature and humidity value. Expect existing aliases on a signal pin:
* pin_dht11
* pin_dht11_direction
Returns a byte showing result status,using constants defined by the lib:
DHT11_OK: successful reading, global variables are set
DHT11_ERR: checksum error while reading
DHT11_TIMEOUT: too many time occurs before readings, give up.
Calling code must check these returned value in order to know if
global variables are actually storing updated values

Include

To use this procedure, include the library:

include temperature_humidity_dht11

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f27j53_dht11.jal

-- Title: DHT11 sample
-- Author: Sebastien Lelong, Copyright (c) 2008..2009, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: this program show how to access DHT11 or DHT22 temperature & humidity sensor.
-- Using Seeedstudio's Grove brick
-- (http://www.seeedstudio.com/depot/grove-temphumi-sensor-p-745.html?cPath=144_147)
-- just power the sensor with 5V or 3V3, connect RA3 pin to SIG pin on the sensor.
-- Results are printed through serial.
-- USE_DHT22 constant is used to handle DHT22 sensor. No such constant means using DHT11
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes: sample adapted from a Jaluino Bee sample
--

include 18f27j53

pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

include delay

-- LED connected on C2
pin_C2_direction =  output
alias led is pin_C2

-- pin A3 is connected to SIG pin on sensor side
alias pin_dht11 is pin_A3
alias pin_dht11_direction is pin_A3_direction
-- lib works with both DHT11 and more accurate DHT22, just declare it
-- so lib is able to talk to the sensor the correct way
const bit USE_DHT22 = true
include temperature_humidity_dht11

-- we'll print results through serial
const SERIAL_HW_BAUDRATE = 9600
include serial_hardware
serial_hw_init()

include print
include format

if defined(USE_DHT22) then
   const byte welcome[] = "-- DHT22 sample --"
else
   const byte welcome[] = "-- DHT11 sample --"
end if
const byte str_status[] = "Reading status: "
const byte str_status_ok[] = "OK"
const byte str_status_err[] = "CHECKSUM ERROR"
const byte str_status_timeout[] = "TIMEOUT"
const byte str_status_unknown[] = "Unknown (weird !)"
const byte str_temperature[] = "Temperature: "
const byte str_humidity[] = "Humidity: "
const byte str_buffer[] = "Raw buffer: "

var byte dht11_status

print_string(serial_hw_data,welcome)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

forever loop
   led = on

   dht11_status = dht11_read()
   print_string(serial_hw_data,str_status)
   if dht11_status == DHT11_OK then
      print_string(serial_hw_data,str_status_ok)
   elsif dht11_status == DHT11_ERR then
      print_string(serial_hw_data,str_status_err)
   elsif dht11_status == DHT11_TIMEOUT then
      print_string(serial_hw_data,str_status_timeout)
   else
      print_string(serial_hw_data,str_status_unknown)
   end if
   print_crlf(serial_hw_data)

   print_string(serial_hw_data,str_temperature)
   format_word_dec(serial_hw_data,dht11_temperature,3,1)
   print_crlf(serial_hw_data)

   print_string(serial_hw_data,str_humidity)
   format_word_dec(serial_hw_data,dht11_humidity,3,1)
   print_crlf(serial_hw_data)

   var byte i
   print_string(serial_hw_data,str_buffer)
   for 5 using i loop
       print_byte_dec(serial_hw_data,_dht11_buffer[i])
       serial_hw_data = " "
   end loop
   print_crlf(serial_hw_data)

   print_crlf(serial_hw_data)
   led = off

   delay_1s(5)
end loop

--

Generated by JALlib CHM Help System | Source: temperature_humidity_dht11.jal


digital_potentiometer_mcp4131.jal - JALLIB Library Documentation

digital_potentiometer_mcp4131.jal JALLIB LIBRARY

Title

Digital potentiometer mcp4131

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2012, all rights reserved., Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library controls digital potentiometer mcp4131

Sources

http://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf

constants

Routines

  • mcp4131_decrement - Procedure
  • mcp4131_increment - Procedure
  • mcp4131_init - Procedure
  • mcp4131_wiper'put - Procedure
  • mcp4131_write - Procedure


digital_potentiometer_x9c10x.jal - JALLIB Library Documentation

digital_potentiometer_x9c10x.jal JALLIB LIBRARY

Title

Digital potentiometer library for X9C102, X9C103, X9C104, X9C503

Author

Rob Jansen, Copyright (c) 2020..2020, all rights reserved., Adapted-by:

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library controls digital potentiometer x9c10x using a 3
wire serial interface. Define the following pins:
-) x9c10x_increment_pin & x9c10x_increment_pin_direction
-) x9c10x_up_down_pin & x9c10x_up_down_pin_direction
-) x9c10x_chip_select_pin & x9c10x_chip_select_pin_direction

Sources

Renesas datasheet for X9C102, X9C103, X9C104, X9C503.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Wiper values, 100 positions.

Constants and Variables

X9C10X_MIN_VALUE - const byte = 0
X9C10X_MAX_VALUE - const byte = 99

Routines

  • x9c10x_decrement - Procedure
  • x9c10x_increment - Procedure
  • x9c10x_init - Procedure
  • x9c10x_store - Procedure
  • x9c10x_wiper'put - Procedure


ds18b20.jal - JALLIB Library Documentation

ds18b20.jal JALLIB LIBRARY

Title

1 wire library for DS18b20

Author

Jean Marchaudon, Copyright (c) 2010..2010, all rights reserved., Adapted-by: And-Tech.pl, Bert van Dam, Jean Marchaudon, Olivier Seit,

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

1 wire routines for the DS18b20 temperature probe
Read sensor temperature DS18b20 from a specific device using the
drive's ID
--
use _s_ procedures when there is only one device on the bus.
use _m_ procedures when there is more than one device on the bus.

Notes

requires 1_wire.jal
----------------------------------------------------------------------------

Sources

ds18b20 datasheet (http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf)

Routines

  • _ds18b20_match_rom - Procedure
  • _ds18b20_read - Function returns bit
  • _ds18b20_skip_rom - Procedure
  • ds18b20_convert - Procedure
  • ds18b20_m_convert - Procedure
  • ds18b20_m_temp - Function returns bit
  • ds18b20_s_read_rom - Function returns bit
  • ds18b20_s_temp - Function returns bit
  • ds18b20_setup - Procedure


ds18b20_convert - JALlib Procedures Help

ds18b20_convert JALLIB PROCEDURE

Signature

procedure ds18b20_convert() is

Description

ds18b20_convert - start conversion of all devices on the bus.
This is actually like an _s_ procedure. When it is executed on a bus with
multiple ds18b20 devices, all will start conversion.

Include

To use this procedure, include the library:

include ds18b20

Parameters

None

Return Value

None

Example

From sample file: 16f648a_ds18b20_single.jal

-- ------------------------------------------------------
-- Title: Test program for ds18b20.jal
--
-- Author: Vasile Guta Ciucur, Copyright (c) 2010..2014, all rights reserved.
--
-- Adapted-by: mkerna@gmail.com, Joep Suijs
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--    Read sensor temperature DS18B20 from a specific device using the
--    drive's ID
--
-- Sources:
--
-- Notes: requires LCD to display result
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_ds18b20_single.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b4              -- LCD command/data select.
alias lcd_rs_direction is pin_b4_direction
alias lcd_en           is pin_b0              -- LCD data trigger
alias lcd_en_direction is pin_b0_direction

alias lcd_dataport is porta_low              -- LCD data  port
alias lcd_dataport_direction is porta_low_direction
const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line

include delay
include print
include format
enable_digital_io()  -- set all IO as digital

-- setup lcd
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include lcd_hd44780_4                -- LCD library with 4 data lines
lcd_init()                           -- initialize LCD
alias device is lcd

-- ----------------------------
-- start of setup ds18b20 stuff
-- ----------------------------

-- setup pin definitions for dallas one-wire bus
alias d1w_bus            is pin_b1
alias d1w_bus_direction  is pin_b1_direction
include one_wire           -- include one-wire library
d1w_init()                 -- init one-wire bus

-- select one of the output formats below
const ds18b20_value_raw          = 0
const ds18b20_value_celcius      = 1
const ds18b20_value_farenheit    = 0

const ds18b20_ignore_crc         = 0 -- 1 tell lib to ignore crc (code becomes smaller and faster, but reliability of data is less)
const ds18b20_max_retries        = 2 -- 1 means the library re-reads once when crc fails, 4 means up to 4 retries (so max 5 reads)

include ds18b20            -- include library for ds18b20 temperature sensor with one-wire interface

-- ---------------------------
-- end of setup ds18b20 stuff
-- ---------------------------

-- strings and vars for the main loop
const byte str1[]       = "Temp="
const byte str_err1[]   = "ds18b20 read failed."
var byte i
var sword temperature
var bit r

forever loop

   ds18b20_convert()  -- tell all ds18b20 devices to start conversion

   -- note: the statement above starts the conversion and it can take
   -- up to 750ms to complete.
   -- If the sensor is in parasite mode, it is mandatory to leave the bus
   -- during conversion. You could include a delay like:
   delay_1ms(750)
   -- If you have other stuff to do, feel free to do so and create proper
   -- timing in an other way.
   --
   -- If the sensor is conventional powered, you don't have to keep the
   -- bus idle and could read the sensor before conversion is complete.
   -- The sensor will return the previous value.

   r = ds18b20_s_temp(temperature)                 -- read conversion result
   lcd_cursor_position(0,0)                        -- first line
   if (r) then
      -- success, so print temperature
      print_string(device, str1)                   -- print string
      format_sword_dec(device, temperature, 4, 1)  -- print temperature in xx.x format
      device = "C"
      device = " "
   else
      -- print fail message
      print_string(device, str_err1)
   end if

   -- read the device's ID and print it
   lcd_cursor_position(1,0)          -- second line

   r = ds18b20_s_read_rom()
   if (r) then
      -- read_rom successful, so print ID which is now stored in scratchpad
      for 8 using i loop
         print_byte_hex(device, scratchpad[i])
      end loop
   else
      -- print fail message
      print_string(device, str_err1)
   end if

end loop

Generated by JALlib CHM Help System | Source: ds18b20.jal


ds18b20_s_read_rom - JALlib Procedures Help

ds18b20_s_read_rom JALLIB FUNCTION

Signature

function ds18b20_s_read_rom() return bit is

Description

ds18b20_s_read_rom - read ID from single device on bus
Only use this procedure when there is only one device on the one_wire bus.
result is 8-byte ID in the scratchpad area
return: true if success (crc okay).

Include

To use this procedure, include the library:

include ds18b20

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f648a_ds18b20_single.jal

-- ------------------------------------------------------
-- Title: Test program for ds18b20.jal
--
-- Author: Vasile Guta Ciucur, Copyright (c) 2010..2014, all rights reserved.
--
-- Adapted-by: mkerna@gmail.com, Joep Suijs
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--    Read sensor temperature DS18B20 from a specific device using the
--    drive's ID
--
-- Sources:
--
-- Notes: requires LCD to display result
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_ds18b20_single.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b4              -- LCD command/data select.
alias lcd_rs_direction is pin_b4_direction
alias lcd_en           is pin_b0              -- LCD data trigger
alias lcd_en_direction is pin_b0_direction

alias lcd_dataport is porta_low              -- LCD data  port
alias lcd_dataport_direction is porta_low_direction
const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line

include delay
include print
include format
enable_digital_io()  -- set all IO as digital

-- setup lcd
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include lcd_hd44780_4                -- LCD library with 4 data lines
lcd_init()                           -- initialize LCD
alias device is lcd

-- ----------------------------
-- start of setup ds18b20 stuff
-- ----------------------------

-- setup pin definitions for dallas one-wire bus
alias d1w_bus            is pin_b1
alias d1w_bus_direction  is pin_b1_direction
include one_wire           -- include one-wire library
d1w_init()                 -- init one-wire bus

-- select one of the output formats below
const ds18b20_value_raw          = 0
const ds18b20_value_celcius      = 1
const ds18b20_value_farenheit    = 0

const ds18b20_ignore_crc         = 0 -- 1 tell lib to ignore crc (code becomes smaller and faster, but reliability of data is less)
const ds18b20_max_retries        = 2 -- 1 means the library re-reads once when crc fails, 4 means up to 4 retries (so max 5 reads)

include ds18b20            -- include library for ds18b20 temperature sensor with one-wire interface

-- ---------------------------
-- end of setup ds18b20 stuff
-- ---------------------------

-- strings and vars for the main loop
const byte str1[]       = "Temp="
const byte str_err1[]   = "ds18b20 read failed."
var byte i
var sword temperature
var bit r

forever loop

   ds18b20_convert()  -- tell all ds18b20 devices to start conversion

   -- note: the statement above starts the conversion and it can take
   -- up to 750ms to complete.
   -- If the sensor is in parasite mode, it is mandatory to leave the bus
   -- during conversion. You could include a delay like:
   delay_1ms(750)
   -- If you have other stuff to do, feel free to do so and create proper
   -- timing in an other way.
   --
   -- If the sensor is conventional powered, you don't have to keep the
   -- bus idle and could read the sensor before conversion is complete.
   -- The sensor will return the previous value.

   r = ds18b20_s_temp(temperature)                 -- read conversion result
   lcd_cursor_position(0,0)                        -- first line
   if (r) then
      -- success, so print temperature
      print_string(device, str1)                   -- print string
      format_sword_dec(device, temperature, 4, 1)  -- print temperature in xx.x format
      device = "C"
      device = " "
   else
      -- print fail message
      print_string(device, str_err1)
   end if

   -- read the device's ID and print it
   lcd_cursor_position(1,0)          -- second line

   r = ds18b20_s_read_rom()
   if (r) then
      -- read_rom successful, so print ID which is now stored in scratchpad
      for 8 using i loop
         print_byte_hex(device, scratchpad[i])
      end loop
   else
      -- print fail message
      print_string(device, str_err1)
   end if

end loop

Generated by JALlib CHM Help System | Source: ds18b20.jal


ds18b20_s_temp - JALlib Procedures Help

ds18b20_s_temp JALLIB FUNCTION

Signature

function ds18b20_s_temp(sword out temperature) return bit is

Description

ds18b20_s_temp - read temperature from single device on bus
Only use this procedure when there is only one device on the one_wire bus.
behavior of this procedure (retry, converions) is influenced by
constants, see lib header.
return: true if success (crc okay).

Include

To use this procedure, include the library:

include ds18b20

Parameters

  • temperature - sword out

Return Value

bit - Function return value

Example

From sample file: 16f648a_ds18b20_single.jal

-- ------------------------------------------------------
-- Title: Test program for ds18b20.jal
--
-- Author: Vasile Guta Ciucur, Copyright (c) 2010..2014, all rights reserved.
--
-- Adapted-by: mkerna@gmail.com, Joep Suijs
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--    Read sensor temperature DS18B20 from a specific device using the
--    drive's ID
--
-- Sources:
--
-- Notes: requires LCD to display result
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_ds18b20_single.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b4              -- LCD command/data select.
alias lcd_rs_direction is pin_b4_direction
alias lcd_en           is pin_b0              -- LCD data trigger
alias lcd_en_direction is pin_b0_direction

alias lcd_dataport is porta_low              -- LCD data  port
alias lcd_dataport_direction is porta_low_direction
const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line

include delay
include print
include format
enable_digital_io()  -- set all IO as digital

-- setup lcd
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include lcd_hd44780_4                -- LCD library with 4 data lines
lcd_init()                           -- initialize LCD
alias device is lcd

-- ----------------------------
-- start of setup ds18b20 stuff
-- ----------------------------

-- setup pin definitions for dallas one-wire bus
alias d1w_bus            is pin_b1
alias d1w_bus_direction  is pin_b1_direction
include one_wire           -- include one-wire library
d1w_init()                 -- init one-wire bus

-- select one of the output formats below
const ds18b20_value_raw          = 0
const ds18b20_value_celcius      = 1
const ds18b20_value_farenheit    = 0

const ds18b20_ignore_crc         = 0 -- 1 tell lib to ignore crc (code becomes smaller and faster, but reliability of data is less)
const ds18b20_max_retries        = 2 -- 1 means the library re-reads once when crc fails, 4 means up to 4 retries (so max 5 reads)

include ds18b20            -- include library for ds18b20 temperature sensor with one-wire interface

-- ---------------------------
-- end of setup ds18b20 stuff
-- ---------------------------

-- strings and vars for the main loop
const byte str1[]       = "Temp="
const byte str_err1[]   = "ds18b20 read failed."
var byte i
var sword temperature
var bit r

forever loop

   ds18b20_convert()  -- tell all ds18b20 devices to start conversion

   -- note: the statement above starts the conversion and it can take
   -- up to 750ms to complete.
   -- If the sensor is in parasite mode, it is mandatory to leave the bus
   -- during conversion. You could include a delay like:
   delay_1ms(750)
   -- If you have other stuff to do, feel free to do so and create proper
   -- timing in an other way.
   --
   -- If the sensor is conventional powered, you don't have to keep the
   -- bus idle and could read the sensor before conversion is complete.
   -- The sensor will return the previous value.

   r = ds18b20_s_temp(temperature)                 -- read conversion result
   lcd_cursor_position(0,0)                        -- first line
   if (r) then
      -- success, so print temperature
      print_string(device, str1)                   -- print string
      format_sword_dec(device, temperature, 4, 1)  -- print temperature in xx.x format
      device = "C"
      device = " "
   else
      -- print fail message
      print_string(device, str_err1)
   end if

   -- read the device's ID and print it
   lcd_cursor_position(1,0)          -- second line

   r = ds18b20_s_read_rom()
   if (r) then
      -- read_rom successful, so print ID which is now stored in scratchpad
      for 8 using i loop
         print_byte_hex(device, scratchpad[i])
      end loop
   else
      -- print fail message
      print_string(device, str_err1)
   end if

end loop

Generated by JALlib CHM Help System | Source: ds18b20.jal


ds1307_init - JALlib Procedures Help

ds1307_init JALLIB PROCEDURE

Signature

procedure ds1307_init() is

Description

rtc initialisation -----------------------------------------------

Include

To use this procedure, include the library:

include rtc_ds1307

Parameters

None

Return Value

None

Example

From sample file: 16f877a_ds1307_sw.jal

-- ------------------------------------------------------
-- Title:  DS1307 - Real Time Clock
--
-- Author: Enzo SERAFINI, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This sample show an example to setup hours, minutes and seconds and display on LCD
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:  Jean-Bernard - DS1307 lib.
--
-- Notes:
--  - File creation date/time: 13 Jun 2011.
--
-- ------------------------------------------------------

include 16f877a                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      HS               -- HS crystal or resonator
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      enabled      -- allow Low Voltage Programming
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

-- lcd config
const byte LCD_ROWS    =  4           -- LCD with 4 lines
const byte LCD_CHARS   =  20          -- and 20 characters per line
--
alias     lcd_en       is pin_D4      -- data trigger
alias     lcd_rs       is pin_D5      -- command/data select.
pin_D4_direction       = output
pin_D5_direction       = output
--
alias     lcd_d4       is pin_D0
alias     lcd_d5       is pin_D1
alias     lcd_d6       is pin_D2
alias     lcd_d7       is pin_D3
--
pin_D0_direction       = output
pin_D1_direction       = output
pin_D2_direction       = output
pin_D3_direction       = output
--
include lcd_hd44780_4
--
lcd_init()                            -- init the lcd controller

-- i2c config
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software    -- include i2c software lib

i2c_initialize()

include delay           -- include delay lib
include print           -- include print lib
include format          -- include format lib

include rtc_ds1307          -- include ds1307 rtc lib

ds1307_init()

-- define strings

var byte str1[] = "Set Time"
var byte str2[] = "hours"
var byte str3[] = "minutes"
var byte str4[] = "seconds"
var byte str5[] = "RTC :"

-- define variables

var byte h , m , s

-- define pins

alias     sw1       is pin_A0
alias     sw2       is pin_A1
alias     sw3       is pin_A2
--
pin_A0_direction       = input
pin_A1_direction       = input
pin_A2_direction       = input

-- Setup hours, minutes and seconds

lcd_cursor_position( 0,0 )
print_string(lcd,str1)                        -- Display "Set Time"
delay_100ms(10)
h = 0
while sw1 != high loop                        -- Setup hours

   if sw2 == high then h = h + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then h = h - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if h == 24 then h = 0 end if
   if h == 255 then h = 23 end if
   lcd_cursor_position( 1,0 )
   print_string(lcd,str2)                    -- Display "hours"
   lcd_cursor_position( 1,9 )
   format_byte_dec(lcd,h,2,0)               -- Display set hours
end loop
delay_100ms(10)
m = 0
while sw1 != high loop                        -- Setup minutes
   if sw2 == high then m = m + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then m = m - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if m == 60 then m = 0 end if
   if m == 255 then m = 59 end if
   lcd_cursor_position( 2,0 )
   print_string(lcd,str3)                    -- Display "minutes"
   lcd_cursor_position( 2,9 )
   format_byte_dec(lcd,m,2,0)               -- Display set minutes
end loop
delay_100ms(10)
s = 0
while sw1 != high loop                        -- Setup seconds
   if sw2 == high then s = s + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then s = s - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if s == 60 then s = 0 end if
   if s == 255 then s = 59 end if
   lcd_cursor_position( 3,0 )
   print_string(lcd,str4)                    -- Display "seconds"
   lcd_cursor_position( 3,9)
   format_byte_dec(lcd,s,2,0)               -- Dsiplay set seconds
end loop

-- write hours, minutes and seconds in the DS1307

ds1307_write( 0x00 , s )      -- seconds
ds1307_write( 0x01 , m )      -- minutes
ds1307_write( 0x02 , h )      -- hours

lcd_clear_line(0)

forever loop

   ds1307_read( 0x00 , s )      -- seconds
   ds1307_read( 0x01 , m )      -- minutes
   ds1307_read( 0x02 , h )      -- hours

   lcd_cursor_position( 0,0 )
   print_string(lcd,str5)        -- Display "RTC :"
   lcd_cursor_position( 0,7 )
   format_time_hms(lcd,h, m,s)   -- Display hh:mm:ss

end loop

Generated by JALlib CHM Help System | Source: rtc_ds1307.jal


ds1307_read - JALlib Procedures Help

ds1307_read JALLIB PROCEDURE

Signature

procedure ds1307_read( byte in ad , byte out d ) is

Description

Title: DS1307 / I2C read write & bcd routines.
Author: Jean-Bernard, Copyright (c) 2001...2011, all rights reserved.
Adapted-by: Enzo SERAFINI,
Rob Hamerling issue #164
Compiler: 2.4p
This file is part of jallib (https://github.com/jallib/jallib)
Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
Description: DS1307 / I2C read write & bcd routines.
Some DS1307 registers
Second adress is 0x00 values 0-59
Minuts adress is 0x01 values 0-59
Hour adress is 0x02 values 0-12 or 0-24
Week day adress is 0x03 values 1-7
Month day adress is 0x04 values 01-28,29,30,31
Month adress is 0x05 values 1-12
Year adress is 0x06 values 0-99
for more details download the pec.sheet
http://pdfserv.maxim-ic.com/arpdf/DS1307.pdf

Include

To use this procedure, include the library:

include rtc_ds1307

Parameters

  • ad - byte in
  • d - byte out

Return Value

None

Example

From sample file: 16f877a_ds1307_sw.jal

-- ------------------------------------------------------
-- Title:  DS1307 - Real Time Clock
--
-- Author: Enzo SERAFINI, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This sample show an example to setup hours, minutes and seconds and display on LCD
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:  Jean-Bernard - DS1307 lib.
--
-- Notes:
--  - File creation date/time: 13 Jun 2011.
--
-- ------------------------------------------------------

include 16f877a                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      HS               -- HS crystal or resonator
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      enabled      -- allow Low Voltage Programming
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

-- lcd config
const byte LCD_ROWS    =  4           -- LCD with 4 lines
const byte LCD_CHARS   =  20          -- and 20 characters per line
--
alias     lcd_en       is pin_D4      -- data trigger
alias     lcd_rs       is pin_D5      -- command/data select.
pin_D4_direction       = output
pin_D5_direction       = output
--
alias     lcd_d4       is pin_D0
alias     lcd_d5       is pin_D1
alias     lcd_d6       is pin_D2
alias     lcd_d7       is pin_D3
--
pin_D0_direction       = output
pin_D1_direction       = output
pin_D2_direction       = output
pin_D3_direction       = output
--
include lcd_hd44780_4
--
lcd_init()                            -- init the lcd controller

-- i2c config
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software    -- include i2c software lib

i2c_initialize()

include delay           -- include delay lib
include print           -- include print lib
include format          -- include format lib

include rtc_ds1307          -- include ds1307 rtc lib

ds1307_init()

-- define strings

var byte str1[] = "Set Time"
var byte str2[] = "hours"
var byte str3[] = "minutes"
var byte str4[] = "seconds"
var byte str5[] = "RTC :"

-- define variables

var byte h , m , s

-- define pins

alias     sw1       is pin_A0
alias     sw2       is pin_A1
alias     sw3       is pin_A2
--
pin_A0_direction       = input
pin_A1_direction       = input
pin_A2_direction       = input

-- Setup hours, minutes and seconds

lcd_cursor_position( 0,0 )
print_string(lcd,str1)                        -- Display "Set Time"
delay_100ms(10)
h = 0
while sw1 != high loop                        -- Setup hours

   if sw2 == high then h = h + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then h = h - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if h == 24 then h = 0 end if
   if h == 255 then h = 23 end if
   lcd_cursor_position( 1,0 )
   print_string(lcd,str2)                    -- Display "hours"
   lcd_cursor_position( 1,9 )
   format_byte_dec(lcd,h,2,0)               -- Display set hours
end loop
delay_100ms(10)
m = 0
while sw1 != high loop                        -- Setup minutes
   if sw2 == high then m = m + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then m = m - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if m == 60 then m = 0 end if
   if m == 255 then m = 59 end if
   lcd_cursor_position( 2,0 )
   print_string(lcd,str3)                    -- Display "minutes"
   lcd_cursor_position( 2,9 )
   format_byte_dec(lcd,m,2,0)               -- Display set minutes
end loop
delay_100ms(10)
s = 0
while sw1 != high loop                        -- Setup seconds
   if sw2 == high then s = s + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then s = s - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if s == 60 then s = 0 end if
   if s == 255 then s = 59 end if
   lcd_cursor_position( 3,0 )
   print_string(lcd,str4)                    -- Display "seconds"
   lcd_cursor_position( 3,9)
   format_byte_dec(lcd,s,2,0)               -- Dsiplay set seconds
end loop

-- write hours, minutes and seconds in the DS1307

ds1307_write( 0x00 , s )      -- seconds
ds1307_write( 0x01 , m )      -- minutes
ds1307_write( 0x02 , h )      -- hours

lcd_clear_line(0)

forever loop

   ds1307_read( 0x00 , s )      -- seconds
   ds1307_read( 0x01 , m )      -- minutes
   ds1307_read( 0x02 , h )      -- hours

   lcd_cursor_position( 0,0 )
   print_string(lcd,str5)        -- Display "RTC :"
   lcd_cursor_position( 0,7 )
   format_time_hms(lcd,h, m,s)   -- Display hh:mm:ss

end loop

Generated by JALlib CHM Help System | Source: rtc_ds1307.jal


ds1307_write - JALlib Procedures Help

ds1307_write JALLIB PROCEDURE

Signature

procedure ds1307_write( byte in ad , byte in d ) is

Description

No description available.

Include

To use this procedure, include the library:

include rtc_ds1307

Parameters

  • ad - byte in
  • d - byte in

Return Value

None

Example

From sample file: 16f877a_ds1307_sw.jal

-- ------------------------------------------------------
-- Title:  DS1307 - Real Time Clock
--
-- Author: Enzo SERAFINI, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This sample show an example to setup hours, minutes and seconds and display on LCD
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:  Jean-Bernard - DS1307 lib.
--
-- Notes:
--  - File creation date/time: 13 Jun 2011.
--
-- ------------------------------------------------------

include 16f877a                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      HS               -- HS crystal or resonator
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      enabled      -- allow Low Voltage Programming
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

-- lcd config
const byte LCD_ROWS    =  4           -- LCD with 4 lines
const byte LCD_CHARS   =  20          -- and 20 characters per line
--
alias     lcd_en       is pin_D4      -- data trigger
alias     lcd_rs       is pin_D5      -- command/data select.
pin_D4_direction       = output
pin_D5_direction       = output
--
alias     lcd_d4       is pin_D0
alias     lcd_d5       is pin_D1
alias     lcd_d6       is pin_D2
alias     lcd_d7       is pin_D3
--
pin_D0_direction       = output
pin_D1_direction       = output
pin_D2_direction       = output
pin_D3_direction       = output
--
include lcd_hd44780_4
--
lcd_init()                            -- init the lcd controller

-- i2c config
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software    -- include i2c software lib

i2c_initialize()

include delay           -- include delay lib
include print           -- include print lib
include format          -- include format lib

include rtc_ds1307          -- include ds1307 rtc lib

ds1307_init()

-- define strings

var byte str1[] = "Set Time"
var byte str2[] = "hours"
var byte str3[] = "minutes"
var byte str4[] = "seconds"
var byte str5[] = "RTC :"

-- define variables

var byte h , m , s

-- define pins

alias     sw1       is pin_A0
alias     sw2       is pin_A1
alias     sw3       is pin_A2
--
pin_A0_direction       = input
pin_A1_direction       = input
pin_A2_direction       = input

-- Setup hours, minutes and seconds

lcd_cursor_position( 0,0 )
print_string(lcd,str1)                        -- Display "Set Time"
delay_100ms(10)
h = 0
while sw1 != high loop                        -- Setup hours

   if sw2 == high then h = h + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then h = h - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if h == 24 then h = 0 end if
   if h == 255 then h = 23 end if
   lcd_cursor_position( 1,0 )
   print_string(lcd,str2)                    -- Display "hours"
   lcd_cursor_position( 1,9 )
   format_byte_dec(lcd,h,2,0)               -- Display set hours
end loop
delay_100ms(10)
m = 0
while sw1 != high loop                        -- Setup minutes
   if sw2 == high then m = m + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then m = m - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if m == 60 then m = 0 end if
   if m == 255 then m = 59 end if
   lcd_cursor_position( 2,0 )
   print_string(lcd,str3)                    -- Display "minutes"
   lcd_cursor_position( 2,9 )
   format_byte_dec(lcd,m,2,0)               -- Display set minutes
end loop
delay_100ms(10)
s = 0
while sw1 != high loop                        -- Setup seconds
   if sw2 == high then s = s + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then s = s - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if s == 60 then s = 0 end if
   if s == 255 then s = 59 end if
   lcd_cursor_position( 3,0 )
   print_string(lcd,str4)                    -- Display "seconds"
   lcd_cursor_position( 3,9)
   format_byte_dec(lcd,s,2,0)               -- Dsiplay set seconds
end loop

-- write hours, minutes and seconds in the DS1307

ds1307_write( 0x00 , s )      -- seconds
ds1307_write( 0x01 , m )      -- minutes
ds1307_write( 0x02 , h )      -- hours

lcd_clear_line(0)

forever loop

   ds1307_read( 0x00 , s )      -- seconds
   ds1307_read( 0x01 , m )      -- minutes
   ds1307_read( 0x02 , h )      -- hours

   lcd_cursor_position( 0,0 )
   print_string(lcd,str5)        -- Display "RTC :"
   lcd_cursor_position( 0,7 )
   format_time_hms(lcd,h, m,s)   -- Display hh:mm:ss

end loop

Generated by JALlib CHM Help System | Source: rtc_ds1307.jal


ds3231_get_temperature - JALlib Procedures Help

ds3231_get_temperature JALLIB FUNCTION

Signature

function ds3231_get_temperature() return sword is

Description

Read the temperature of the DS3231 and return the value. The value is given
in Celsius with a 0.25 resolution. A value of 23.25 degrees is returned
as 2325.
Note: This is a specific DS3231 feature, not an rtc feature.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


dsm_clear_indicator - JALlib Procedures Help

dsm_clear_indicator JALLIB PROCEDURE

Signature

procedure dsm_clear_indicator(word in data) is

Description

dsm_clear_indicator - set one or more indicators

Include

To use this procedure, include the library:

include lcd_dsm0822a

Parameters

  • data - word in

Return Value

None

Example

From sample file: 16f723_lcd_dsm0822a.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: LCD DSM0822A star burst display test program
--
-- Sources:
--
-- Notes:
--    setup: a dsm0822a display, connected via i2c
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f723_af.jal
--    * test : test_lcd_dsm0822a.jal
--

;@jallib section chipdef

-- device include
include 16f723

-- Internal osc, running at 16 MHz
pragma target clock 16_000_000

-- fuses
pragma target OSC INTOSC_NOCLKOUT
pragma target WDT DISABLED
pragma target PWRTE DISABLED
pragma target MCLR INTERNAL
pragma target CP DISABLED
pragma target BROWNOUT DISABLED
pragma target VOLTAGE V19
pragma target PLLEN ENABLED
pragma target VCAPEN pin_A0
;@jallib section i2c
-- I2C io definition, using hardware I2C
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- inculde dsm0822a libraray & init                                                                                                                                                    const byte I2C_port = 0
include lcd_dsm0822a
dsm_init()

const byte str1[] = "\nStar ";
print_string(dsm_data, str1);  -- print 'Star' ('\n' sets cursor at home position)

dsm_data = ASCII_CR  -- set cursor back at home position

var byte ch = " "

forever loop

   -- 'walk' the strength indicator
   dsm_clear_indicator(DSM_I1 | DSM_I2 | DSM_I3)   -- clear all strength indicators
   dsm_set_indicator(DSM_I1)     -- set left strength indicators
   delay_100ms(3)

   dsm_clear_indicator(DSM_I1)   -- clear the left indicator
   dsm_set_indicator(DSM_I2)     -- set the middle one
   delay_100ms(3)

   dsm_clear_indicator(DSM_I2)   -- clear the middle indicator
   dsm_set_indicator(DSM_I3)     -- set the rigth one
   delay_100ms(3)

   dsm_clear_indicator(DSM_I3)   -- clear the right indicator
   delay_100ms(3)

   -- put the next character on screen
   dsm_data = ch        ; put char on display
   ch = ch + 1          ; next char
   if (ch > "_") then   ; if beyond last char
      ch = " "          ; then start over
   end if

end loop

Generated by JALlib CHM Help System | Source: lcd_dsm0822a.jal


dsm_init - JALlib Procedures Help

dsm_init JALLIB PROCEDURE

Signature

procedure dsm_init() is

Description

init & clear display

Include

To use this procedure, include the library:

include lcd_dsm0822a

Parameters

None

Return Value

None

Example

From sample file: 16f723_lcd_dsm0822a.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: LCD DSM0822A star burst display test program
--
-- Sources:
--
-- Notes:
--    setup: a dsm0822a display, connected via i2c
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f723_af.jal
--    * test : test_lcd_dsm0822a.jal
--

;@jallib section chipdef

-- device include
include 16f723

-- Internal osc, running at 16 MHz
pragma target clock 16_000_000

-- fuses
pragma target OSC INTOSC_NOCLKOUT
pragma target WDT DISABLED
pragma target PWRTE DISABLED
pragma target MCLR INTERNAL
pragma target CP DISABLED
pragma target BROWNOUT DISABLED
pragma target VOLTAGE V19
pragma target PLLEN ENABLED
pragma target VCAPEN pin_A0
;@jallib section i2c
-- I2C io definition, using hardware I2C
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- inculde dsm0822a libraray & init                                                                                                                                                    const byte I2C_port = 0
include lcd_dsm0822a
dsm_init()

const byte str1[] = "\nStar ";
print_string(dsm_data, str1);  -- print 'Star' ('\n' sets cursor at home position)

dsm_data = ASCII_CR  -- set cursor back at home position

var byte ch = " "

forever loop

   -- 'walk' the strength indicator
   dsm_clear_indicator(DSM_I1 | DSM_I2 | DSM_I3)   -- clear all strength indicators
   dsm_set_indicator(DSM_I1)     -- set left strength indicators
   delay_100ms(3)

   dsm_clear_indicator(DSM_I1)   -- clear the left indicator
   dsm_set_indicator(DSM_I2)     -- set the middle one
   delay_100ms(3)

   dsm_clear_indicator(DSM_I2)   -- clear the middle indicator
   dsm_set_indicator(DSM_I3)     -- set the rigth one
   delay_100ms(3)

   dsm_clear_indicator(DSM_I3)   -- clear the right indicator
   delay_100ms(3)

   -- put the next character on screen
   dsm_data = ch        ; put char on display
   ch = ch + 1          ; next char
   if (ch > "_") then   ; if beyond last char
      ch = " "          ; then start over
   end if

end loop

Generated by JALlib CHM Help System | Source: lcd_dsm0822a.jal


dsm_set_indicator - JALlib Procedures Help

dsm_set_indicator JALLIB PROCEDURE

Signature

procedure dsm_set_indicator(word in data) is

Description

dsm_set_indicator - set one or more indicators

Include

To use this procedure, include the library:

include lcd_dsm0822a

Parameters

  • data - word in

Return Value

None

Example

From sample file: 16f723_lcd_dsm0822a.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: LCD DSM0822A star burst display test program
--
-- Sources:
--
-- Notes:
--    setup: a dsm0822a display, connected via i2c
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f723_af.jal
--    * test : test_lcd_dsm0822a.jal
--

;@jallib section chipdef

-- device include
include 16f723

-- Internal osc, running at 16 MHz
pragma target clock 16_000_000

-- fuses
pragma target OSC INTOSC_NOCLKOUT
pragma target WDT DISABLED
pragma target PWRTE DISABLED
pragma target MCLR INTERNAL
pragma target CP DISABLED
pragma target BROWNOUT DISABLED
pragma target VOLTAGE V19
pragma target PLLEN ENABLED
pragma target VCAPEN pin_A0
;@jallib section i2c
-- I2C io definition, using hardware I2C
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- inculde dsm0822a libraray & init                                                                                                                                                    const byte I2C_port = 0
include lcd_dsm0822a
dsm_init()

const byte str1[] = "\nStar ";
print_string(dsm_data, str1);  -- print 'Star' ('\n' sets cursor at home position)

dsm_data = ASCII_CR  -- set cursor back at home position

var byte ch = " "

forever loop

   -- 'walk' the strength indicator
   dsm_clear_indicator(DSM_I1 | DSM_I2 | DSM_I3)   -- clear all strength indicators
   dsm_set_indicator(DSM_I1)     -- set left strength indicators
   delay_100ms(3)

   dsm_clear_indicator(DSM_I1)   -- clear the left indicator
   dsm_set_indicator(DSM_I2)     -- set the middle one
   delay_100ms(3)

   dsm_clear_indicator(DSM_I2)   -- clear the middle indicator
   dsm_set_indicator(DSM_I3)     -- set the rigth one
   delay_100ms(3)

   dsm_clear_indicator(DSM_I3)   -- clear the right indicator
   delay_100ms(3)

   -- put the next character on screen
   dsm_data = ch        ; put char on display
   ch = ch + 1          ; next char
   if (ch > "_") then   ; if beyond last char
      ch = " "          ; then start over
   end if

end loop

Generated by JALlib CHM Help System | Source: lcd_dsm0822a.jal


dtmf_encoder_ht9200.jal - JALLIB Library Documentation

dtmf_encoder_ht9200.jal JALLIB LIBRARY

Title

HT9200 DTMF generator library

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Select a DTMF signal to be generated by HT9200.

Notes

Sound is only generated while chip select is LOW
This chip is ment to use 5 bit SPI, so the CS line must be toggled for
each data byte sent since the SPI libraries are 8 bit.
This chip uses SPI mode 1,1 but may work with other modes.

Tone output frequency table
Bits are reversed for LSB spi

Routines

  • hd9200_dial - Procedure
  • hd9200_digit - Procedure
  • hd9200_send - Procedure


ee25_read - JALlib Procedures Help

ee25_read JALLIB FUNCTION

Signature

function ee25_read(byte in addr) return byte is

Description

read the data from the specified address

Include

To use this procedure, include the library:

include ee_25aa02e48

Parameters

  • addr - byte in

Return Value

byte - Function return value

Example

From sample file: 16f819_ee25aa02e48_lcd.jal

-- Title: Read back the EUI-48 address and display on STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Read back the 'MAC address' from the serial EEprom, also do a simple
--                 test of writing to eeprom and reading back.
--
-- This file has been generated by hand (manually maintained)
--

include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "    EUI-48 "

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

-- disable external CAN controller which
-- is present on this prototype board.
alias can_sel is pin_B0
can_sel = 1
pin_B0_direction = output

alias ee25_sel is pin_A1
ee25_sel = 1
pin_A1_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include ee_25aa02e48

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

const byte pattern_expected[4] = { 0xAA, 0x55, 0x00, 0xFF }
var byte mac_expected[6], mac[6], pattern[4]
var word mac_errs = 0
var word pat_errs = 0
var byte i

-- read mac address from eeprom
for 6 using i loop
   var byte data
   data = ee25_read(0xFA + i)
   mac_expected[i] = data
end loop

-- write data pattern to EEprom, loc: 0-3
for 4 using i loop
   ee25_write(i, pattern_expected[i])
end loop

-- display initial values
lcd_cursor_position(2,0)
for 6 using i loop
   print_byte_hex(lcd, mac_expected[i])
end loop

lcd_cursor_position(3,0)
for 4 using i loop
   print_byte_hex(lcd, pattern_expected[i])
end loop

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

forever loop

   -- read mac address from eeprom
   for 6 using i loop
      var byte data
      data = ee25_read(0xFA + i)
      mac[i] = data
   end loop

   -- read the data pattern back from loc: 0-3
   for 4 using i loop
      var byte data
      data = ee25_read(i)
      pattern[i] = data
   end loop

   -- compare
   for 6 using i loop
      if mac[i] != mac_expected[i] then
         mac_errs = mac_errs + 1
      end if
   end loop

   for 4 using i loop
      if pattern[i] != pattern_expected[i] then
         pat_errs = pat_errs + 1
      end if
   end loop

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   lcd_cursor_position(1,0)
   print_word_hex(lcd, mac_errs)
   lcd = " "
   print_word_hex(lcd, pat_errs)

   -- display current value
   lcd_cursor_position(2,0)
   for 6 using i loop
      print_byte_hex(lcd, mac[i])
   end loop

   lcd_cursor_position(3,0)
   for 4 using i loop
      print_byte_hex(lcd, pattern[i])
   end loop

   led = led ^ 1
   delay_100ms(1)
end loop

Generated by JALlib CHM Help System | Source: ee_25aa02e48.jal


ee25_write - JALlib Procedures Help

ee25_write JALLIB PROCEDURE

Signature

procedure ee25_write(byte in addr, byte in data) is

Description

write the data to the specified address.

Include

To use this procedure, include the library:

include ee_25aa02e48

Parameters

  • addr - byte in
  • data - byte in

Return Value

None

Example

From sample file: 16f819_ee25aa02e48_lcd.jal

-- Title: Read back the EUI-48 address and display on STERM or other LCD display
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Sponsored by: Fiwihex www.fiwihex.com
-- Compiler: 2.4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Read back the 'MAC address' from the serial EEprom, also do a simple
--                 test of writing to eeprom and reading back.
--
-- This file has been generated by hand (manually maintained)
--

include 16f819
pragma target fuses 0x3F30
pragma target clock 8_000_000
include delay

OSCCON = 0x70
asm nop
asm nop

include format
include print

const byte banner[] = "    EUI-48 "

enable_digital_io()

alias led is pin_A0
pin_A0_direction =  output

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_A4
var bit lcd_sterm_pin_dir is pin_A4_direction
include lcd_sterm_master

-- disable external CAN controller which
-- is present on this prototype board.
alias can_sel is pin_B0
can_sel = 1
pin_B0_direction = output

alias ee25_sel is pin_A1
ee25_sel = 1
pin_A1_direction = output
pin_B1_direction = input
pin_B2_direction = output
pin_B4_direction = output
include spi_master_hw
include ee_25aa02e48

spi_init(SPI_MODE_00, SPI_RATE_FOSC_64)
delay_100ms(1)

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   led = led ^ 1
   delay_100ms(5)
end loop

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)

const byte pattern_expected[4] = { 0xAA, 0x55, 0x00, 0xFF }
var byte mac_expected[6], mac[6], pattern[4]
var word mac_errs = 0
var word pat_errs = 0
var byte i

-- read mac address from eeprom
for 6 using i loop
   var byte data
   data = ee25_read(0xFA + i)
   mac_expected[i] = data
end loop

-- write data pattern to EEprom, loc: 0-3
for 4 using i loop
   ee25_write(i, pattern_expected[i])
end loop

-- display initial values
lcd_cursor_position(2,0)
for 6 using i loop
   print_byte_hex(lcd, mac_expected[i])
end loop

lcd_cursor_position(3,0)
for 4 using i loop
   print_byte_hex(lcd, pattern_expected[i])
end loop

-- leave banner up for a while
for 25 loop
   led = led ^ 1
   delay_100ms(2)
end loop

forever loop

   -- read mac address from eeprom
   for 6 using i loop
      var byte data
      data = ee25_read(0xFA + i)
      mac[i] = data
   end loop

   -- read the data pattern back from loc: 0-3
   for 4 using i loop
      var byte data
      data = ee25_read(i)
      pattern[i] = data
   end loop

   -- compare
   for 6 using i loop
      if mac[i] != mac_expected[i] then
         mac_errs = mac_errs + 1
      end if
   end loop

   for 4 using i loop
      if pattern[i] != pattern_expected[i] then
         pat_errs = pat_errs + 1
      end if
   end loop

   -- wiggle the top-left corner
   lcd_home()
   if led != 0 then
      lcd = "/"
   else
      lcd = "-"
   end if

   -- now the status line
   lcd_cursor_position(1,0)
   print_word_hex(lcd, mac_errs)
   lcd = " "
   print_word_hex(lcd, pat_errs)

   -- display current value
   lcd_cursor_position(2,0)
   for 6 using i loop
      print_byte_hex(lcd, mac[i])
   end loop

   lcd_cursor_position(3,0)
   for 4 using i loop
      print_byte_hex(lcd, pattern[i])
   end loop

   led = led ^ 1
   delay_100ms(1)
end loop

Generated by JALlib CHM Help System | Source: ee_25aa02e48.jal


ee_24lc256_read - JALlib Procedures Help

ee_24lc256_read JALLIB PROCEDURE

Signature

procedure ee_24lc256_read(byte in ic_address, word in mem_address, byte out data) is

Description

Read data from 24LC256 at input address

Include

To use this procedure, include the library:

include eeprom_24lc256

Parameters

  • ic_address - byte in
  • mem_address - word in
  • data - byte out

Return Value

None

Example

From sample file: 18f4550_24lc256.jal

-- Title: 24LC256 i2c eeprom example
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example read and write to 24lc256 i2c eeprom
--
-- Sources:
-- http://groups.google.com/group/jallib
--
-- This file has been generated by Matt's sample generator.
--

include 18f4550                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target PLLDIV   P1           -- no divide
pragma target CPUDIV   P1           -- no Fosc divisor
pragma target WDT      CONTROL      -- watchdog
pragma target XINST    DISABLED     -- not supported by JalV2
pragma target DEBUG    DISABLED     -- no debugging
pragma target IESO     DISABLED     -- no in/ext oscillator switchover
pragma target LVP      ENABLED      -- allow Low Voltage Programming
pragma target MCLR     EXTERNAL     -- reset externally
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- setup i2c software master
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl            is pin_scl
alias i2c_scl_direction  is pin_scl_direction
alias i2c_sda            is pin_sda
alias i2c_sda_direction  is pin_sda_direction
--
include i2c_software
i2c_initialize()

include eeprom_24lc256 -- include 24lc256 eeprom

-- start of main program

var byte data
forever loop
   ee_24lc256_write(0xA0, 1, "A")  -- write "A" to 24lc256

   ee_24lc256_read(0xA0, 1, data)  -- read from 24lc256

   serial_hw_write(data)            -- send the data via serial port 4 times
   serial_hw_write(data)            -- recieved data should be "AAAA"
   serial_hw_write(data)
   serial_hw_write(data)

   _usec_delay (500_000)            -- wait half a second then loop
end loop

Generated by JALlib CHM Help System | Source: eeprom_24lc256.jal


ee_24lc256_write - JALlib Procedures Help

ee_24lc256_write JALLIB PROCEDURE

Signature

procedure ee_24lc256_write(byte in ic_address, word in mem_address, byte in data) is

Description

Write data to 24LC256 at input address

Include

To use this procedure, include the library:

include eeprom_24lc256

Parameters

  • ic_address - byte in
  • mem_address - word in
  • data - byte in

Return Value

None

Example

From sample file: 18f4550_24lc256.jal

-- Title: 24LC256 i2c eeprom example
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example read and write to 24lc256 i2c eeprom
--
-- Sources:
-- http://groups.google.com/group/jallib
--
-- This file has been generated by Matt's sample generator.
--

include 18f4550                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target PLLDIV   P1           -- no divide
pragma target CPUDIV   P1           -- no Fosc divisor
pragma target WDT      CONTROL      -- watchdog
pragma target XINST    DISABLED     -- not supported by JalV2
pragma target DEBUG    DISABLED     -- no debugging
pragma target IESO     DISABLED     -- no in/ext oscillator switchover
pragma target LVP      ENABLED      -- allow Low Voltage Programming
pragma target MCLR     EXTERNAL     -- reset externally
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- setup i2c software master
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl            is pin_scl
alias i2c_scl_direction  is pin_scl_direction
alias i2c_sda            is pin_sda
alias i2c_sda_direction  is pin_sda_direction
--
include i2c_software
i2c_initialize()

include eeprom_24lc256 -- include 24lc256 eeprom

-- start of main program

var byte data
forever loop
   ee_24lc256_write(0xA0, 1, "A")  -- write "A" to 24lc256

   ee_24lc256_read(0xA0, 1, data)  -- read from 24lc256

   serial_hw_write(data)            -- send the data via serial port 4 times
   serial_hw_write(data)            -- recieved data should be "AAAA"
   serial_hw_write(data)
   serial_hw_write(data)

   _usec_delay (500_000)            -- wait half a second then loop
end loop

Generated by JALlib CHM Help System | Source: eeprom_24lc256.jal


ee_25aa02e48.jal - JALLIB Library Documentation

ee_25aa02e48.jal JALLIB LIBRARY

Title

External SPI bus 2K EEPROM with EUI-48 Node Identity

Author

William Welch Copyright (c) 2009, all rights reserved.

Compiler

2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

-- The 25AA02E48 is pre-programmed with a unique EUI-48 address but also
allows for user-generated non-volatile storage.
Note: uses SPI Master library and also needs a 'chip select' pin such as:
alias ee25_sel is pin_A1

The 6-byte EUI-48 node address value is stored at locations 0xFA thru 0xFF. Otherwise,
the chip appears to be the same as the 25AA020A EEPROM.

read the data from the specified address

Routines

  • ee25_rd_status - Function returns byte
  • ee25_read - Function returns byte
  • ee25_wr_status - Procedure
  • ee25_write - Procedure


eeprom_24lc02.jal - JALLIB Library Documentation

eeprom_24lc02.jal JALLIB LIBRARY

Title

24LC02 i2c eeprom library

Author

Matthew Schinkel, copyright (c) 2010, all rights reserved., Adapted-by: William Welch

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

read and write to 24lc02 i2c eeprom
Functions descriptions:
ee_24lc02_read -- Read data from 24LC02 at input address
ee_24lc02_write -- Write data to 24LC02 at input address

Sources

http://groups.google.com/group/jallib

------------------------------------------------------------------------------
Read data from 24LC02 at input address
------------------------------------------------------------------------------

Routines

  • ee_24lc02_read - Procedure
  • ee_24lc02_write - Procedure


eeprom_24lc256.jal - JALLIB Library Documentation

eeprom_24lc256.jal JALLIB LIBRARY

Title

24LC256 i2c eeprom library

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

read and write to 24lc256 i2c eeprom
Functions descriptions:
ee_24lc256_read -- Read data from 24LC256 at input address
ee_24lc256_write -- Write data to 24LC256 at input address

Sources

http://groups.google.com/group/jallib

------------------------------------------------------------------------------
Read data from 24LC256 at input address
------------------------------------------------------------------------------

Routines

  • ee_24lc256_read - Procedure
  • ee_24lc256_write - Procedure


enc28j60.jal - JALLIB Library Documentation

enc28j60.jal JALLIB LIBRARY

Title

Ethernet Device ENC28j60

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

controls the ehernet device ENC28j60 for networking.

Sources

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889
enc28j60 C library by Pascal Stang
enc28j60 C library by Guido Socher

Constants and Variables

enc_current_bank - var byte
enc_packet_pointer - var word = 0
RXSTOP_INIT - const word = (0x1FFF-0x0600-1) -- =0x19FE
=0x19FE
RXSTOP_INIT_H - const byte = 0x19
RXSTOP_INIT_L - const byte = 0xFE
TXSTART_INIT - const word = (0x1FFF-0x0600) -- =0x19FF
=0x19FF
TXSTART_INIT_H - const byte = 0x19
TXSTART_INIT_L - const byte = 0xFF
TXSTOP_INIT - const word = 0x1FFF
TXSTOP_INIT_H - const byte = 0x1F
TXSTOP_INIT_L - const byte = 0xFF
ENC_MAX_FRAMELEN - const word = 1500 -- =0x05DC
=0x05DC
ENC_MAX_FRAMELEN_H - const byte = 0x05
ENC_MAX_FRAMELEN_L - const byte = 0xDC

Routines

  • enc_array'put - Procedure
  • enc_clear_rx_buffer - Procedure
  • enc_complete_packet_read - Procedure
  • enc_end_packet - Procedure
  • enc_init - Procedure
  • enc_packet_available'get - Function returns bit
  • enc_packet_size'get - Function returns word
  • enc_packets_available - Function returns byte
  • enc_read_buffer - Procedure
  • enc_read_register - Function returns byte
  • enc_read_revision - Function returns byte
  • enc_rx_buffer'get - Function returns byte
  • enc_set_bank - Procedure
  • enc_set_clkout_freq - Procedure
  • enc_spi_read_command - Function returns byte
  • enc_spi_write_command - Procedure
  • enc_tx_buffer'put - Procedure
  • enc_write_buffer - Procedure
  • enc_write_phy_register - Procedure
  • enc_write_register - Procedure


enc_init - JALlib Procedures Help

enc_init JALLIB PROCEDURE

Signature

procedure enc_init() is

Description

No description available.

Include

To use this procedure, include the library:

include enc28j60

Parameters

None

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: enc28j60.jal


enc_read_revision - JALlib Procedures Help

enc_read_revision JALLIB FUNCTION

Signature

function enc_read_revision() return byte is

Description

read the revision of the device

Include

To use this procedure, include the library:

include enc28j60

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: enc28j60.jal


enc_set_clkout_freq - JALlib Procedures Help

enc_set_clkout_freq JALLIB PROCEDURE

Signature

procedure enc_set_clkout_freq(byte in clk) is

Description

set clkout pin frequency
0b11x = Reserved for factory test. Do not use. Glitch prevention not assured.
5 = CLKOUT outputs main clock divided by 8 (3.125 MHz)
4 = CLKOUT outputs main clock divided by 4 (6.25 MHz)
3 = CLKOUT outputs main clock divided by 3 (8.333333 MHz)
2 = CLKOUT outputs main clock divided by 2 (12.5 MHz)
1 = CLKOUT outputs main clock divided by 1 (25 MHz)
0 = CLKOUT is disabled. The pin is driven low.

Include

To use this procedure, include the library:

include enc28j60

Parameters

  • clk - byte in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: enc28j60.jal


esp8266.jal - JALLIB Library Documentation

esp8266.jal JALLIB LIBRARY

Title

ESP8266 Library for interfacing with an ESP8266 module via the USART.

Author

Rob Jansen, Copyright (c) 2018..2019, all rights reserved., Adapted-by:

Compiler

2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

------------
Library for using the ESP8266 Wifi Module based on version 2.0.0 of the
ESP8166 AT command set. Some functionality provided by this library:
-) Supports Wifi, TCP, UDP and SSL
-) Supports client and server mode
-) Supports mutlti connection mode
Dependencies:
-------------
This library uses the first USART for communicating with the ESP8266. Due to
the high communication speed with the ESP8266 it uses the interrupt driven
USART library with the default buffer sizes. See serial_hw_int_cts.jal for
more information on these buffer sizes.
For big data reception it also includes the large_array_1.jal library.

Notes

------
In order to make the use of this library more easy, all public pins
constants, variable, functions and procedures are mentioned at the
start of this library.
Since the ESP8266 uses the USART as interface, function and procedure
paramaters are mostly character (string) based.
When using the device as web server, a sufficiently large receive buffer is
needed as to be able to parse all received data.
This library was tested using an ESP8266 ESP-12F.
--------------------------Public pins ---------------------------------------
Make sure you have defined the USART1 pins!
alias pin_RX_direction is pin_xx_direction -- PIC depending.
alias pin_TX_direction is pin_xx_direction -- PIC depending.

--------------------Public constant declarations -----------------------------

Sources

--------
Inspired by https://github.com/bportaluri/WiFiEsp
See ESP8266 Instruction Set version 2.0.0 and
https://room-15.github.io/blog/2015/03/26/esp8266-at-command-reference/

Constants and Variables

ESP8266_MODE_STATION - const byte = 1
ESP8266_MODE_AP - const byte = 2
ESP8266_MODE_AP_STATION - const byte = 3
ESP8266_IDLE - const byte = 0
ESP8266_CONNECTED - const byte = 1
ESP8266_DISCONNECTED - const byte = 2
ESP8266_ERROR - const byte = 3
ESP8266_DEFAULT_CONNECTION - const byte = 0
LARGE_ARRAY_1_SIZE - const word = ESP8266_MAX_RECEIVE_BUFFER
LARGE_ARRAY_1_VARIABLE_SIZE - const word = 1 -- Array of bytes.
Array of bytes.
esp8266_bytes_received - var word

Routines

  • _esp8266_acknowledge - Function returns bit
  • _esp8266_check_response - Function returns bit
  • _esp8266_client_start - Function returns bit
  • _esp8266_copy_response - Procedure
  • _esp8266_extract_item - Function returns bit
  • _esp8266_flush_serial_receive_buffer - Procedure
  • _esp8266_get_character - Function returns bit
  • _esp8266_send_data - Procedure
  • _esp8266_strip_double_quoto - Function returns bit
  • esp8266_alive - Function returns bit
  • esp8266_client_start_ssl - Function returns bit
  • esp8266_client_start_tcp - Function returns bit
  • esp8266_client_start_udp - Function returns bit
  • esp8266_client_stop - Function returns bit
  • esp8266_close_connection - Function returns bit
  • esp8266_connect_to_ap - Function returns bit
  • esp8266_data_available - Function returns bit
  • esp8266_disconnect_from_ap - Function returns bit
  • esp8266_get_ap_ip_address - Function returns bit
  • esp8266_get_bssid - Function returns bit
  • esp8266_get_channel - Function returns bit
  • esp8266_get_connection - Function returns byte
  • esp8266_get_connection_status - Function returns byte
  • esp8266_get_data - Function returns bit
  • esp8266_get_ip_address - Function returns bit
  • esp8266_get_mac_address - Function returns bit
  • esp8266_get_rssi - Function returns bit
  • esp8266_get_ssid - Function returns bit
  • esp8266_give_serial_byte - Procedure
  • esp8266_init - Function returns bit
  • esp8266_ping - Function returns bit
  • esp8266_reset - Function returns bit
  • esp8266_restore - Function returns bit
  • esp8266_send_data - Function returns bit
  • esp8266_server_start - Function returns bit
  • esp8266_server_stop - Function returns bit
  • esp8266_set_ap_ip_address - Function returns bit
  • esp8266_set_connection - Procedure
  • esp8266_set_server_timeout - Function returns bit
  • esp8266_start_ap - Function returns bit


esp8266_client_start_tcp - JALlib Procedures Help

esp8266_client_start_tcp JALLIB FUNCTION

Signature

function esp8266_client_start_tcp(byte in host[], byte in port[]) return bit is

Description

Start a client tcp connection and return TRUE if connected. Note that when there
was already a connection, FALSE is returned.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • host[] - byte in
  • port[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_client.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web client sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- This program connects to the example website using an ESP8266 module and
-- will send a HTTP request to the website every 5 seconds. The website response
-- will be written to the second USART. Results can be monitors on the PC using
-- a Terminal Emulator program.
-- Note that the website sends a lot of data which cannot all be handled by the
-- programm but the intention of this program is to show that it works.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- -------------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate = 115200  -- Terminal connection.

-- We need a big buffer for the web server.
const ESP8266_MAX_RECEIVE_BUFFER = 1600

-- We also need a bigger serial buffer for the first USART used by the esp8266.
-- 80 is maximum. This is still not sufficient, see remark at the end of this
-- sample program.
const SERIAL_RCVBUFSIZE  = 80

-- Set the request repeat time to 5 seconds.
const word REQUEST_TIME   = 50_000

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_HOST[]     = "www.example.com"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var word request_counter
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web client program for ESP8266.\n")

-- Initialize the device and connect to the AP until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

print_string(serial_hw2_data,"Pinging host ...")
if esp8266_ping(MY_HOST) then
   print_string(serial_hw2_data," succes.\n")
else
   print_string(serial_hw2_data," failed.\n")
end if

-- We start with a request, so get the initial (default) connection number.
connection = esp8266_get_connection()

print_string(serial_hw2_data,"Starting connection to host ...")
if esp8266_client_start_tcp(MY_HOST, MY_PORT) then
   print_string(serial_hw2_data," connected.\n")
else
   print_string(serial_hw2_data,"failed.\n")
end if

request_counter = 0
forever loop
   _usec_delay(100) -- Loop time.

   -- Check if a request must be sent.
   if (request_counter == REQUEST_TIME) then
      request_counter = 0
      print_string(serial_hw2_data,"Requesting some data ...")
      -- Make sure that the request goes to the this connection.
      esp8266_set_connection(connection)
      all_ok = esp8266_send_data("GET / HTTP/1.1\r\n")
      all_ok = all_ok & esp8266_send_data("Host: ")
      all_ok = all_ok & esp8266_send_data(MY_HOST)
      all_ok = all_ok & esp8266_send_data("\r\n")
      all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
      if all_ok then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      print_crlf(serial_hw2_data)
   else
      request_counter = request_counter + 1
   end if

   -- Poll the device and print the data that is coming from the server.
   if esp8266_data_available() then
      print_string(serial_hw2_data,"Data present\r\n")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received ")
         print_maxvar_dec(serial_hw2_data, esp8266_bytes_received)
         print_string(serial_hw2_data," bytes.\r\n")
         -- One remark here. The ESP8266 does not transmit the whole website in
         -- one packet which means that while printing the receive buffer data
         -- is also received from the ESP module. Although the serial buffer is
         -- increased to 80, it is not sufficient so not all data is displayed.
         -- Because of that it will also mention that incorrect data is received
         -- which is caused by not processing the incoming data fast enough.
         print_receive_buffer()
         print_crlf(serial_hw2_data)
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_close_connection - JALlib Procedures Help

esp8266_close_connection JALLIB FUNCTION

Signature

function esp8266_close_connection() return bit is

Description

Close the currently set connection. Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_connect_to_ap - JALlib Procedures Help

esp8266_connect_to_ap JALLIB FUNCTION

Signature

function esp8266_connect_to_ap(byte in ssid[], byte in password[]) return bit is

Description

Connect to access point not saving this to flash. For use of special
characters in the parameters see the instruction set of the ESP8266.
Returns TRUE if succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • ssid[] - byte in
  • password[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_data_available - JALlib Procedures Help

esp8266_data_available JALLIB FUNCTION

Signature

function esp8266_data_available() return bit is

Description

Returns TRUE if data is present in the serial buffer. The data must be
processes as soon as possible using the function esp8266_get_data().

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_bssid - JALlib Procedures Help

esp8266_get_bssid JALLIB FUNCTION

Signature

function esp8266_get_bssid() return bit is

Description

Returns the BSSID of the ESP8266 module in the receive buffer of the ESP8266.
Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_tcp_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 TCP server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
--  This example starts a TCP server. To test as follows:
--  -) Start the application and wait until it has been connected to your AP.
--     Make sure you have set the right SSID and password in 'MY_SSID' and
--     'MY_PASSWORD'.
--  -) Start a terminal emulation program on your computer so that you can see
--     which information is send via the second USART connection (the first
--     USART connection is used by the ESP8266 library).
--  -) Start a Telnet session on your computer. Make sure that 'MY_HOST' is set
--     to the IP address of your computer.
--  -) In Telnet open a connecton o the ESP8266 module using the IP address
--     assigned to it (note that IP address of the module is printed by this
--     application) using the port as defined by 'MY_PORT,
--     e.g: o 192.168.1.14 80
--  -) Start typing characters in the Telnet window. They should appear on your
--     screen via the terminal emulator progra.
--  -) Each time valid data is received by the module, the message 'Thanks!' is
--     sent back to the PC which should appear in the Telnet Window.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ----------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200  -- Terminal connection.

-- We do not need a large esp8266 receive buffer, change the default.
const ESP8266_MAX_RECEIVE_BUFFER = 30

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80"  -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var bit all_ok
var bit received_data

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

received_data = FALSE
print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample TCP server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

-- Start the server until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server ...")
   if esp8266_server_start(MY_PORT) then
      print_string(serial_hw2_data," started.\n")
      all_ok = TRUE
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open a Telnet window to connect to IP address ")
   print_receive_buffer()
   print_string(serial_hw2_data," and port ")
   print_string(serial_hw2_data,MY_PORT)
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the device and print the data that is coming from the server.
   while esp8266_data_available() loop
      print_string(serial_hw2_data,"Data - ")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received: ")
         print_receive_buffer()
         print_crlf(serial_hw2_data)
         received_data = TRUE
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
      -- Before we will send something back we accept more data to be received
      -- since the data is sent is small packages from the Telnet window.
      -- Note that this delay can only be used if the data entry is slow.
      _usec_delay(500_000)
   end loop

   -- We return a thank when we have received something.
   if received_data then
      print_string(serial_hw2_data,"Sending some data back ...")
      -- Make sure that the response we will send goes to the this connection.
      esp8266_set_connection(connection)
      if esp8266_send_data("Thanks!\r\n") then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      received_data = FALSE
   end if

end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_channel - JALlib Procedures Help

esp8266_get_channel JALLIB FUNCTION

Signature

function esp8266_get_channel() return bit is

Description

Returns the channel to which the ESP8266 module is connected in the receive
buffer of the ESP8266. Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_tcp_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 TCP server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
--  This example starts a TCP server. To test as follows:
--  -) Start the application and wait until it has been connected to your AP.
--     Make sure you have set the right SSID and password in 'MY_SSID' and
--     'MY_PASSWORD'.
--  -) Start a terminal emulation program on your computer so that you can see
--     which information is send via the second USART connection (the first
--     USART connection is used by the ESP8266 library).
--  -) Start a Telnet session on your computer. Make sure that 'MY_HOST' is set
--     to the IP address of your computer.
--  -) In Telnet open a connecton o the ESP8266 module using the IP address
--     assigned to it (note that IP address of the module is printed by this
--     application) using the port as defined by 'MY_PORT,
--     e.g: o 192.168.1.14 80
--  -) Start typing characters in the Telnet window. They should appear on your
--     screen via the terminal emulator progra.
--  -) Each time valid data is received by the module, the message 'Thanks!' is
--     sent back to the PC which should appear in the Telnet Window.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ----------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200  -- Terminal connection.

-- We do not need a large esp8266 receive buffer, change the default.
const ESP8266_MAX_RECEIVE_BUFFER = 30

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80"  -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var bit all_ok
var bit received_data

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

received_data = FALSE
print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample TCP server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

-- Start the server until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server ...")
   if esp8266_server_start(MY_PORT) then
      print_string(serial_hw2_data," started.\n")
      all_ok = TRUE
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open a Telnet window to connect to IP address ")
   print_receive_buffer()
   print_string(serial_hw2_data," and port ")
   print_string(serial_hw2_data,MY_PORT)
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the device and print the data that is coming from the server.
   while esp8266_data_available() loop
      print_string(serial_hw2_data,"Data - ")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received: ")
         print_receive_buffer()
         print_crlf(serial_hw2_data)
         received_data = TRUE
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
      -- Before we will send something back we accept more data to be received
      -- since the data is sent is small packages from the Telnet window.
      -- Note that this delay can only be used if the data entry is slow.
      _usec_delay(500_000)
   end loop

   -- We return a thank when we have received something.
   if received_data then
      print_string(serial_hw2_data,"Sending some data back ...")
      -- Make sure that the response we will send goes to the this connection.
      esp8266_set_connection(connection)
      if esp8266_send_data("Thanks!\r\n") then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      received_data = FALSE
   end if

end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_connection - JALlib Procedures Help

esp8266_get_connection JALLIB FUNCTION

Signature

function esp8266_get_connection() return byte is

Description

Get the currently set connection number

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_connection_status - JALlib Procedures Help

esp8266_get_connection_status JALLIB FUNCTION

Signature

function esp8266_get_connection_status() return byte is

Description

Return the connection status of the ESP8266. Status can be:
ESP8266_IDEL, ESP8266_CONNECTED, ESP8266_DISCONNECTED, ESP8266_ERROR

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_data - JALlib Procedures Help

esp8266_get_data JALLIB FUNCTION

Signature

function esp8266_get_data(byte out connection) return bit is

Description

Call this function when data is available. The serial data is processed and
copied to the global receive buffer. It returns TRUE when all data is
correctly processed and it returns the connection number from which the
data was received. Note that more data can be received than we can handle
in the receive buffer. Because of that we copy no more bytes than can be
stored in the receive buffer. All remaining data will then be lost.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • connection - byte out

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_ip_address - JALlib Procedures Help

esp8266_get_ip_address JALLIB FUNCTION

Signature

function esp8266_get_ip_address() return bit is

Description

Returns the local IP address as a string in the ESP8266 receive buffer and
returns TRUE when succesfull. For example you can get the following responses:
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"1a:fe:34:f3:02:cd"
+CIFSR:STAIP,"10.0.0.11"
+CIFSR:STAMAC,"18:fe:34:f3:02:cd"
It returns the string without quotes, so: 10.0.0.11

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_mac_address - JALlib Procedures Help

esp8266_get_mac_address JALLIB FUNCTION

Signature

function esp8266_get_mac_address() return bit is

Description

Returns the local MAC address as a string in the ESP8266 receive buffer and
returns TRUE when succesfull. For example you can get the following responses:
+CIFSR:APIP,"192.168.4.1"
+CIFSR:APMAC,"1a:fe:34:f3:02:cd"
+CIFSR:STAIP,"10.0.0.11"
+CIFSR:STAMAC,"18:fe:34:f3:02:cd"
It returns the string without quotes, so: 18:fe:34:f3:02:cd

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_tcp_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 TCP server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
--  This example starts a TCP server. To test as follows:
--  -) Start the application and wait until it has been connected to your AP.
--     Make sure you have set the right SSID and password in 'MY_SSID' and
--     'MY_PASSWORD'.
--  -) Start a terminal emulation program on your computer so that you can see
--     which information is send via the second USART connection (the first
--     USART connection is used by the ESP8266 library).
--  -) Start a Telnet session on your computer. Make sure that 'MY_HOST' is set
--     to the IP address of your computer.
--  -) In Telnet open a connecton o the ESP8266 module using the IP address
--     assigned to it (note that IP address of the module is printed by this
--     application) using the port as defined by 'MY_PORT,
--     e.g: o 192.168.1.14 80
--  -) Start typing characters in the Telnet window. They should appear on your
--     screen via the terminal emulator progra.
--  -) Each time valid data is received by the module, the message 'Thanks!' is
--     sent back to the PC which should appear in the Telnet Window.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ----------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200  -- Terminal connection.

-- We do not need a large esp8266 receive buffer, change the default.
const ESP8266_MAX_RECEIVE_BUFFER = 30

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80"  -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var bit all_ok
var bit received_data

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

received_data = FALSE
print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample TCP server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

-- Start the server until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server ...")
   if esp8266_server_start(MY_PORT) then
      print_string(serial_hw2_data," started.\n")
      all_ok = TRUE
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open a Telnet window to connect to IP address ")
   print_receive_buffer()
   print_string(serial_hw2_data," and port ")
   print_string(serial_hw2_data,MY_PORT)
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the device and print the data that is coming from the server.
   while esp8266_data_available() loop
      print_string(serial_hw2_data,"Data - ")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received: ")
         print_receive_buffer()
         print_crlf(serial_hw2_data)
         received_data = TRUE
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
      -- Before we will send something back we accept more data to be received
      -- since the data is sent is small packages from the Telnet window.
      -- Note that this delay can only be used if the data entry is slow.
      _usec_delay(500_000)
   end loop

   -- We return a thank when we have received something.
   if received_data then
      print_string(serial_hw2_data,"Sending some data back ...")
      -- Make sure that the response we will send goes to the this connection.
      esp8266_set_connection(connection)
      if esp8266_send_data("Thanks!\r\n") then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      received_data = FALSE
   end if

end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_rssi - JALlib Procedures Help

esp8266_get_rssi JALLIB FUNCTION

Signature

function esp8266_get_rssi() return bit is

Description

Returns the rssi of the ESP8266 module in the receive buffer of the ESP8266.
Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_tcp_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 TCP server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
--  This example starts a TCP server. To test as follows:
--  -) Start the application and wait until it has been connected to your AP.
--     Make sure you have set the right SSID and password in 'MY_SSID' and
--     'MY_PASSWORD'.
--  -) Start a terminal emulation program on your computer so that you can see
--     which information is send via the second USART connection (the first
--     USART connection is used by the ESP8266 library).
--  -) Start a Telnet session on your computer. Make sure that 'MY_HOST' is set
--     to the IP address of your computer.
--  -) In Telnet open a connecton o the ESP8266 module using the IP address
--     assigned to it (note that IP address of the module is printed by this
--     application) using the port as defined by 'MY_PORT,
--     e.g: o 192.168.1.14 80
--  -) Start typing characters in the Telnet window. They should appear on your
--     screen via the terminal emulator progra.
--  -) Each time valid data is received by the module, the message 'Thanks!' is
--     sent back to the PC which should appear in the Telnet Window.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ----------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200  -- Terminal connection.

-- We do not need a large esp8266 receive buffer, change the default.
const ESP8266_MAX_RECEIVE_BUFFER = 30

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80"  -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var bit all_ok
var bit received_data

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

received_data = FALSE
print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample TCP server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

-- Start the server until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server ...")
   if esp8266_server_start(MY_PORT) then
      print_string(serial_hw2_data," started.\n")
      all_ok = TRUE
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open a Telnet window to connect to IP address ")
   print_receive_buffer()
   print_string(serial_hw2_data," and port ")
   print_string(serial_hw2_data,MY_PORT)
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the device and print the data that is coming from the server.
   while esp8266_data_available() loop
      print_string(serial_hw2_data,"Data - ")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received: ")
         print_receive_buffer()
         print_crlf(serial_hw2_data)
         received_data = TRUE
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
      -- Before we will send something back we accept more data to be received
      -- since the data is sent is small packages from the Telnet window.
      -- Note that this delay can only be used if the data entry is slow.
      _usec_delay(500_000)
   end loop

   -- We return a thank when we have received something.
   if received_data then
      print_string(serial_hw2_data,"Sending some data back ...")
      -- Make sure that the response we will send goes to the this connection.
      esp8266_set_connection(connection)
      if esp8266_send_data("Thanks!\r\n") then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      received_data = FALSE
   end if

end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_get_ssid - JALlib Procedures Help

esp8266_get_ssid JALLIB FUNCTION

Signature

function esp8266_get_ssid() return bit is

Description

Returns the SSID to which the ESP8266 module is connected in the receive
buffer of the ESP8266. Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_tcp_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 TCP server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
--  This example starts a TCP server. To test as follows:
--  -) Start the application and wait until it has been connected to your AP.
--     Make sure you have set the right SSID and password in 'MY_SSID' and
--     'MY_PASSWORD'.
--  -) Start a terminal emulation program on your computer so that you can see
--     which information is send via the second USART connection (the first
--     USART connection is used by the ESP8266 library).
--  -) Start a Telnet session on your computer. Make sure that 'MY_HOST' is set
--     to the IP address of your computer.
--  -) In Telnet open a connecton o the ESP8266 module using the IP address
--     assigned to it (note that IP address of the module is printed by this
--     application) using the port as defined by 'MY_PORT,
--     e.g: o 192.168.1.14 80
--  -) Start typing characters in the Telnet window. They should appear on your
--     screen via the terminal emulator progra.
--  -) Each time valid data is received by the module, the message 'Thanks!' is
--     sent back to the PC which should appear in the Telnet Window.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ----------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200  -- Terminal connection.

-- We do not need a large esp8266 receive buffer, change the default.
const ESP8266_MAX_RECEIVE_BUFFER = 30

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80"  -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var bit all_ok
var bit received_data

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

received_data = FALSE
print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample TCP server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

-- Start the server until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server ...")
   if esp8266_server_start(MY_PORT) then
      print_string(serial_hw2_data," started.\n")
      all_ok = TRUE
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open a Telnet window to connect to IP address ")
   print_receive_buffer()
   print_string(serial_hw2_data," and port ")
   print_string(serial_hw2_data,MY_PORT)
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the device and print the data that is coming from the server.
   while esp8266_data_available() loop
      print_string(serial_hw2_data,"Data - ")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received: ")
         print_receive_buffer()
         print_crlf(serial_hw2_data)
         received_data = TRUE
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
      -- Before we will send something back we accept more data to be received
      -- since the data is sent is small packages from the Telnet window.
      -- Note that this delay can only be used if the data entry is slow.
      _usec_delay(500_000)
   end loop

   -- We return a thank when we have received something.
   if received_data then
      print_string(serial_hw2_data,"Sending some data back ...")
      -- Make sure that the response we will send goes to the this connection.
      esp8266_set_connection(connection)
      if esp8266_send_data("Thanks!\r\n") then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      received_data = FALSE
   end if

end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_init - JALlib Procedures Help

esp8266_init JALLIB FUNCTION

Signature

function esp8266_init() return bit is

Description

Initialze the serial interface and reset the ESP module. Returns TRUE if
succesful.

Include

To use this procedure, include the library:

include esp8266

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_ping - JALlib Procedures Help

esp8266_ping JALLIB FUNCTION

Signature

function esp8266_ping(byte in host[]) return bit is

Description

Ping to the host and return TRUE when succesful.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • host[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_client.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web client sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- This program connects to the example website using an ESP8266 module and
-- will send a HTTP request to the website every 5 seconds. The website response
-- will be written to the second USART. Results can be monitors on the PC using
-- a Terminal Emulator program.
-- Note that the website sends a lot of data which cannot all be handled by the
-- programm but the intention of this program is to show that it works.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- -------------------------------- Pragmas ---------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate = 115200  -- Terminal connection.

-- We need a big buffer for the web server.
const ESP8266_MAX_RECEIVE_BUFFER = 1600

-- We also need a bigger serial buffer for the first USART used by the esp8266.
-- 80 is maximum. This is still not sufficient, see remark at the end of this
-- sample program.
const SERIAL_RCVBUFSIZE  = 80

-- Set the request repeat time to 5 seconds.
const word REQUEST_TIME   = 50_000

-- WiFi connection constants.
const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_HOST[]     = "www.example.com"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var word request_counter
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

procedure print_wifi_status() is
   if esp8266_get_ssid() then
      print_string(serial_hw2_data,"SSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining SSID.\n")
   end if

   if esp8266_get_bssid() then
      print_string(serial_hw2_data,"BSSID: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining BSSID.\n")
   end if

   if esp8266_get_ip_address() then
      print_string(serial_hw2_data,"Local IP address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local IP address.\n")
   end if

   if esp8266_get_mac_address() then
      print_string(serial_hw2_data,"Local MAC address is: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining local MAC address.\n")
   end if

   if esp8266_get_channel() then
      print_string(serial_hw2_data,"Channel: ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining channel.\n")
   end if

   if esp8266_get_rssi() then
      print_string(serial_hw2_data,"Signal Strength (RSSI): ")
      print_receive_buffer()
      print_crlf(serial_hw2_data)
   else
      print_string(serial_hw2_data,"Error obtaining signal strength.\n")
   end if
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web client program for ESP8266.\n")

-- Initialize the device and connect to the AP until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

print_wifi_status()

print_string(serial_hw2_data,"Pinging host ...")
if esp8266_ping(MY_HOST) then
   print_string(serial_hw2_data," succes.\n")
else
   print_string(serial_hw2_data," failed.\n")
end if

-- We start with a request, so get the initial (default) connection number.
connection = esp8266_get_connection()

print_string(serial_hw2_data,"Starting connection to host ...")
if esp8266_client_start_tcp(MY_HOST, MY_PORT) then
   print_string(serial_hw2_data," connected.\n")
else
   print_string(serial_hw2_data,"failed.\n")
end if

request_counter = 0
forever loop
   _usec_delay(100) -- Loop time.

   -- Check if a request must be sent.
   if (request_counter == REQUEST_TIME) then
      request_counter = 0
      print_string(serial_hw2_data,"Requesting some data ...")
      -- Make sure that the request goes to the this connection.
      esp8266_set_connection(connection)
      all_ok = esp8266_send_data("GET / HTTP/1.1\r\n")
      all_ok = all_ok & esp8266_send_data("Host: ")
      all_ok = all_ok & esp8266_send_data(MY_HOST)
      all_ok = all_ok & esp8266_send_data("\r\n")
      all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
      if all_ok then
         print_string(serial_hw2_data," succes!\n")
      else
         print_string(serial_hw2_data," failed!\n")
      end if
      print_crlf(serial_hw2_data)
   else
      request_counter = request_counter + 1
   end if

   -- Poll the device and print the data that is coming from the server.
   if esp8266_data_available() then
      print_string(serial_hw2_data,"Data present\r\n")
      if esp8266_get_data(connection) then
         print_string(serial_hw2_data,"Received ")
         print_maxvar_dec(serial_hw2_data, esp8266_bytes_received)
         print_string(serial_hw2_data," bytes.\r\n")
         -- One remark here. The ESP8266 does not transmit the whole website in
         -- one packet which means that while printing the receive buffer data
         -- is also received from the ESP module. Although the serial buffer is
         -- increased to 80, it is not sufficient so not all data is displayed.
         -- Because of that it will also mention that incorrect data is received
         -- which is caused by not processing the incoming data fast enough.
         print_receive_buffer()
         print_crlf(serial_hw2_data)
      else
         print_string(serial_hw2_data,"Incorrect.\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_send_data - JALlib Procedures Help

esp8266_send_data JALLIB FUNCTION

Signature

function esp8266_send_data(byte in command[]) return bit is

Description

Sends the given string via the ESP8266 to the current connection.
Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • command[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_server_start - JALlib Procedures Help

esp8266_server_start JALLIB FUNCTION

Signature

function esp8266_server_start(byte in port[]) return bit is

Description

Start TCP server on specified port. Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • port[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_set_connection - JALlib Procedures Help

esp8266_set_connection JALLIB PROCEDURE

Signature

procedure esp8266_set_connection(byte in link_id) is

Description

Set the connection number to be used when sending a response.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • link_id - byte in

Return Value

None

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


esp8266_set_server_timeout - JALlib Procedures Help

esp8266_set_server_timeout JALLIB FUNCTION

Signature

function esp8266_set_server_timeout(byte in timeout[]) return bit is

Description

Set TCP server timeout. Timeout is given in miliseconds. "0" means not
timeout. Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include esp8266

Parameters

  • timeout[] - byte in

Return Value

bit - Function return value

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: esp8266.jal


ethernet_mac.jal - JALLIB Library Documentation

ethernet_mac.jal JALLIB LIBRARY

Title

Ethernet Header BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

creates an ethernet header. contains destination/source
and next protocol type.

Sources

http://www.iana.org/assignments/ethernet-numbers

Routines

  • ethernet_header_create - Procedure
  • ethernet_print_mac - Procedure
  • ethernet_read_packet - Procedure
  • ethernet_verify_header - Function returns bit


fat32.jal - JALLIB Library Documentation

fat32.jal JALLIB LIBRARY

Title

FAT32 library for reading fat32 filesystem (beta version)

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4k

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library reads files & folders from a fat32 formatted media
such as sd cards & hard disks. BETA VERSION!

Notes

exFAT & fat16 are not supported. ONLY USE FAT32!
Windows won't format a sd_card > 32gb with FAT32. Use a 3rd party software (or linux?)
This lib does not create file_name's on fat32 partitions, although it may
in the future. Please see this article http://www.desktoplinux.com/news/NS4980952387.html?kc=rss
before you think about implementing writing of file_names into your project.
some of the following may not be correct in this beta version
"file location list info"
choose max number of files, choose highest entry address (file_name's address).
eg. chosen -> FAT32_ENTRIES_MAX = 1, FAT32_FILES_MAX = 30 and there are 3 files A, B & C all in c:\
File A is in sector 0, entry 6. file B is in sector 4, entry 2. file C is in sector 50, entry 2.
file A is entry address 0*16 + 6 = 6, file B is entry address 4*16 + 2 = 64, file C is entry address 50*16 + 2 = 802
therefore, file C is out of range and will not be accessable due to fragmentation of the directory structure.
memory space required is byte*1 times 30 = 30bytes
the theoretical max number of files for this config is 256 if
there have been no deleted files and all names are short file_names.
if you choose FAT32_ENTRIES_MAX = 2 you will use 2 times 30 = 60bytes and the
theoretical max number of files for this config is 65535
--here's an example:
;const byte FAT32_ENTRIES_MAX = 1 -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2 -- highest file entry address can be 65535
;var byte*FAT32_ENTRIES_MAX fat32_entry_location[FAT32_FILES_MAX] -- we will use large_array library instead
Default uses internal memory for file location list. You may add an
external memory source if you want to have a large amount
of files in a directory. see the sample file
Debug:
-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_0 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)
Known issues:
Can't write to the end of a file if out of file fragment boundaries
Can't write a file_name if out of dir fragment boundaries
TODO:
make file delete procedure.
maybe allow showing of deleted files in directory.
error checking, this could be done by the user instead??
add a check to see if lib loaded ok (add to sample file).
try to reduce data/ram usage. any ideas?? I have to go through everything.
support writing of long file names.
can/should I combine read/write procedures.
change all reads of sector_buffer to use buffer_low[], buffer_high[] (faster)
some procedures may not be needed anymore.
check fat32_file_sectors_available procedure, not working.
update disk usage variable (in boot sector?) during change of file size.
see if I can get rid of fat32_short_file_name array. Is it needed?
need dir_referesh procedure. Maybe just alias fat32_read_dir_info()
do we really need to specify what to get/put in fat32_file_entry_data?
make list partitions procedure.
create file rename procedure
create file delete procedure
one file does not show size/cluster correctly (#4)
rename fat32_set_file_size to fat32_file_set_size

----- GENERAL SETTINGS & VARS -------

vars you can read info from

Sources

http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
http://www.pjrc.com/tech/8051/ide/fat32.html
http://en.wikipedia.org/wiki/File_Allocation_Table
http://en.wikipedia.org/wiki/8.3_filename
http://www.ntfs.com/fat-filenames.htm

Constants and Variables

fat32_init_ok - var bit = FALSE -- tells you if fat32 initalized ok or not.
tells you if fat32 initalized ok or not.
fat32_file_attrib - var byte
fat32_file_attrib_filter - var byte = 0 -- default is do not filter any file attributes
default is do not filter any file attributes
FAT32_DIRECTORY - const byte = 0
FAT32_FILE - const byte = 1
fat32_current_cluster - var dword
fat32_current_sector - var dword = 20
FAT32_ENTRY_DELETED - const byte = 0xE5 -- usually from a deleted file
usually from a deleted file
FAT32_ENTRY_IS_PART_OF_LONG_NAME - const byte = 0x0F -- entry has a few characters of a long file_name
entry has a few characters of a long file_name
current_address - var dword = 0xFFFFFFFF

Routines

  • _fat32_create_fat_clusters - Procedure
  • _fat32_read_boot_sector - Procedure
  • _fat32_read_dir_info - Procedure
  • _fat32_read_dir_sector_number - Procedure
  • _fat32_read_fragments - Procedure
  • _fat32_read_fragments - Procedure
  • _fat32_read_fragments - Procedure
  • _fat32_remove_fat_clusters - Procedure
  • _fat32_set_size - Procedure
  • _fat32_write_dir_sector_number - Procedure
  • fat32_cd - Function returns bit
  • fat32_cluster'get - Function returns dword
  • fat32_cluster'put - Procedure
  • fat32_cluster_in_sector_buffer'get - Function returns dword
  • fat32_cluster_in_sector_buffer'put - Procedure
  • fat32_dir_create - Function returns byte
  • fat32_dir_set_size - Procedure
  • fat32_entry_delete - Procedure
  • fat32_file_close - Procedure
  • fat32_file_create - Function returns byte
  • fat32_file_delete - Procedure
  • fat32_file_entry_data - Procedure
  • fat32_file_open - Function returns bit
  • fat32_file_remove - Procedure
  • fat32_file_sectors_available'get - Function returns dword
  • fat32_file_set_size - Procedure
  • fat32_init - Procedure
  • fat32_print_directory - Procedure
  • fat32_print_file_info - Procedure
  • fat32_print_sector_buffer_hex - Procedure
  • fat32_read_file_byte - Function returns byte
  • fat32_read_file_byte_address - Function returns byte
  • fat32_read_file_info - Procedure
  • fat32_read_file_sector - Procedure
  • fat32_read_file_sector_number - Procedure
  • fat32_start_file_read - Procedure
  • fat32_start_file_write - Procedure
  • fat32_write_file_sector - Procedure
  • fat32_write_file_sector_number - Procedure
  • fat_restore - Procedure


fat32_cd - JALlib Procedures Help

fat32_cd JALLIB FUNCTION

Signature

function fat32_cd(byte*FAT32_ENTRIES_MAX in file_number) return bit is

Description

change directory, returns 1 = success, 0 = not a directory

Include

To use this procedure, include the library:

include fat32

Parameters

  • file_number - byte*FAT32_ENTRIES_MAX in

Return Value

bit - Function return value

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_file_close - JALlib Procedures Help

fat32_file_close JALLIB PROCEDURE

Signature

procedure fat32_file_close() is

Description

close the currently opened file.

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_file_open - JALlib Procedures Help

fat32_file_open JALLIB FUNCTION

Signature

function fat32_file_open(byte*FAT32_ENTRIES_MAX in file_number) return bit is

Description

check if file is ok to start reading, returns 1 = success, 0 = not a file

Include

To use this procedure, include the library:

include fat32

Parameters

  • file_number - byte*FAT32_ENTRIES_MAX in

Return Value

bit - Function return value

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_init - JALlib Procedures Help

fat32_init JALLIB PROCEDURE

Signature

procedure fat32_init(byte in primary_partition_number) is

Description

initalize fat32

Include

To use this procedure, include the library:

include fat32

Parameters

  • primary_partition_number - byte in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_print_directory - JALlib Procedures Help

fat32_print_directory JALLIB PROCEDURE

Signature

procedure fat32_print_directory(volatile byte out output_device, byte in options) is

Description

print the current directory to an output device. Use same options as
in fat32_print_file_info

Include

To use this procedure, include the library:

include fat32

Parameters

  • output_device - byte out
  • options - byte in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_print_file_info - JALlib Procedures Help

fat32_print_file_info JALLIB PROCEDURE

Signature

procedure fat32_print_file_info(volatile byte out output_device, byte in options) is

Description

Print a file_name to an output device. Use the following constants as
input options.

Include

To use this procedure, include the library:

include fat32

Parameters

  • output_device - byte out
  • options - byte in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_read_file_byte - JALlib Procedures Help

fat32_read_file_byte JALLIB FUNCTION

Signature

function fat32_read_file_byte() return byte is

Description

read one byte from a file starting at the beginning of the file.
auto increments to next byte in file. fragmented files work.
requires: fat32_start_file_read(fat32_file_location), fat32_stop_file_read()
faster then fat32_read_file_address() procedure

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_read_file_byte_address - JALlib Procedures Help

fat32_read_file_byte_address JALLIB FUNCTION

Signature

function fat32_read_file_byte_address(dword in address) return byte is

Description

reads selected byte from a file. fragmented files work.
slower then fat32_read_file() procedure, but user friendly.

Include

To use this procedure, include the library:

include fat32

Parameters

  • address - dword in

Return Value

byte - Function return value

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_read_file_info - JALlib Procedures Help

fat32_read_file_info JALLIB PROCEDURE

Signature

procedure fat32_read_file_info(byte*FAT32_ENTRIES_MAX in file_number) is

Description

reads file info such as file_name, file size, filelocation, etc. into memory.

Include

To use this procedure, include the library:

include fat32

Parameters

  • file_number - byte*FAT32_ENTRIES_MAX in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_read_file_sector - JALlib Procedures Help

fat32_read_file_sector JALLIB PROCEDURE

Signature

procedure fat32_read_file_sector() is

Description

read one sector from a file starting at the beginning of the file.
auto increments to next sector in file. fragmented files work.
requires: fat32_start_file_read(fat32_file_location), fat32_stop_file_read()
faster then fat32_read_file_sector_number() procedure

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_read_file_sector_number - JALlib Procedures Help

fat32_read_file_sector_number JALLIB PROCEDURE

Signature

procedure fat32_read_file_sector_number(dword in file_sector_number) is

Description

reads selected sector from a file. fragmented files work.
slower then fat32_read_file_sector() procedure, but user friendly.

Include

To use this procedure, include the library:

include fat32

Parameters

  • file_sector_number - dword in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_small.jal - JALLIB Library Documentation

fat32_small.jal JALLIB LIBRARY

Title

FAT32-small sample for reading fat32 filesystem

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4k

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library reads files & folders from a fat32 formatted
sd card. This small version only supports the first partition,
and only one file.

Notes

1. First format your device with fat32 before using this library.
2. Do not put other files onto the storage device. This library will
overwrite and erase existing files on the storage device because
only one file is supported, and no fragments are supported.

Sources

http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
http://www.pjrc.com/tech/8051/ide/fat32.html
http://en.wikipedia.org/wiki/File_Allocation_Table

Constants and Variables

FAT32_SMALL_FILE_LOCATION - const dword = 0x03
fat32_small_open_for_write - var bit = FALSE
fat32_small_open_for_read - var bit = FALSE

Routines

  • fat32_small_file_close - Procedure
  • fat32_small_file_open - Procedure
  • fat32_small_file_read - Procedure
  • fat32_small_file_write - Procedure
  • fat32_small_init - Procedure
  • fat32_small_read_boot_sector - Procedure
  • fat32_small_set_file_size - Procedure


fat32_small_file_close - JALlib Procedures Help

fat32_small_file_close JALLIB PROCEDURE

Signature

procedure fat32_small_file_close() is

Description

Close the file

Include

To use this procedure, include the library:

include fat32_small

Parameters

None

Return Value

None

Example

From sample file: 18f4620_fat32_small_sd_card.jal

-- Title: FAT32-small sample for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example reads files & folders from a fat32 formatted storage
--              device using the fat32-small library. This small version only
--              supports the first partition, and only one file.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- Notes:
-- 1. First format your device with fat32 before using this library.
-- 2. Do not put other files onto the storage device. This sample will
--    overwrite and erase existing files on the storage device because
--    only one file is supported, and no fragments are supported.
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- setup fat32 --
const FAT32_SMALL_SMALL_VERSION  = TRUE          -- use the small version of fat32
const FAT32_SMALL_VOL_ID[11]     = "Vol_ID     " -- 11 byte volume id (name of partition)
const FAT32_SMALL_FILE_NAME[8]   = "DATA    "    -- 8 byte file name (name of the 1 file allowed)
const FAT32_SMALL_FILE_EXT[3]    = "DAT"         -- 3 byte file extension (extension of the 1 file allowed)
const FAT32_SMALL_MAX_FILE_SIZE  = 50000        -- max file size
const byte FAT32_SMALL_ATTRIBUTE = 0x20          -- the file attributes
--
include fat32_small   -- include small fat32 library

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   print_crlf(serial_data)
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port.
separator()             -- send "----" via serial port
print_crlf(serial_data)
var byte start_string[] = "FAT32 SMALL - SAMPLE STARTED"
print_string(serial_data,start_string)
separator()             -- send "----" via serial port
print_crlf(serial_data)

fat32_small_init() -- initalize data media

-- WRITE TO THE FILE
var dword new_file_size_count -- count how many bytes you have written
-- open the file, at file sector number 0 (the beginning of the file)
fat32_small_file_open(0)
for 3000 using new_file_size_count loop             -- loop 200 times
   fat32_small_file_write("J") -- write each data byte
end loop
fat32_small_file_close() -- close the file

-- update the file size on the storage device
fat32_small_set_file_size(new_file_size_count)

-- READ THE FILE
var byte x
fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
   fat32_small_file_read(x)    -- get one byte of data
   serial_data = x          -- send it to the serial port
end loop
fat32_small_file_close()       -- close the file

;   -- WRITE TO THE END OF THE FILE
;   --
;   -- calculate the next available sector
;   var dword address = (fat32_small_file_size / 512) + 1
;   fat32_small_file_open(address)                     -- open the file
;   for 200 using new_file_size_count loop             -- loop 200 times
;      fat32_small_file_write("K") -- write each data byte
;   end loop
;   fat32_small_file_close() -- close the file
;
;   -- set the new file size
;   fat32_small_set_file_size((address * 512) + new_file_size_count)
;
;   print_crlf(serial_data)
;   print_crlf(serial_data)
;
;   -- READ THE ENTIRE FILE AGAIN
;   fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
;   for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
;      fat32_small_file_read(x)    -- get one byte of data
;      serial_data = x          -- send it to the serial port
;   end loop
;   fat32_small_file_close()       -- close the file

Generated by JALlib CHM Help System | Source: fat32_small.jal


fat32_small_file_open - JALlib Procedures Help

fat32_small_file_open JALLIB PROCEDURE

Signature

procedure fat32_small_file_open(dword in file_sector_number) is

Description

Open the file

Include

To use this procedure, include the library:

include fat32_small

Parameters

  • file_sector_number - dword in

Return Value

None

Example

From sample file: 18f4620_fat32_small_sd_card.jal

-- Title: FAT32-small sample for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example reads files & folders from a fat32 formatted storage
--              device using the fat32-small library. This small version only
--              supports the first partition, and only one file.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- Notes:
-- 1. First format your device with fat32 before using this library.
-- 2. Do not put other files onto the storage device. This sample will
--    overwrite and erase existing files on the storage device because
--    only one file is supported, and no fragments are supported.
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- setup fat32 --
const FAT32_SMALL_SMALL_VERSION  = TRUE          -- use the small version of fat32
const FAT32_SMALL_VOL_ID[11]     = "Vol_ID     " -- 11 byte volume id (name of partition)
const FAT32_SMALL_FILE_NAME[8]   = "DATA    "    -- 8 byte file name (name of the 1 file allowed)
const FAT32_SMALL_FILE_EXT[3]    = "DAT"         -- 3 byte file extension (extension of the 1 file allowed)
const FAT32_SMALL_MAX_FILE_SIZE  = 50000        -- max file size
const byte FAT32_SMALL_ATTRIBUTE = 0x20          -- the file attributes
--
include fat32_small   -- include small fat32 library

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   print_crlf(serial_data)
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port.
separator()             -- send "----" via serial port
print_crlf(serial_data)
var byte start_string[] = "FAT32 SMALL - SAMPLE STARTED"
print_string(serial_data,start_string)
separator()             -- send "----" via serial port
print_crlf(serial_data)

fat32_small_init() -- initalize data media

-- WRITE TO THE FILE
var dword new_file_size_count -- count how many bytes you have written
-- open the file, at file sector number 0 (the beginning of the file)
fat32_small_file_open(0)
for 3000 using new_file_size_count loop             -- loop 200 times
   fat32_small_file_write("J") -- write each data byte
end loop
fat32_small_file_close() -- close the file

-- update the file size on the storage device
fat32_small_set_file_size(new_file_size_count)

-- READ THE FILE
var byte x
fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
   fat32_small_file_read(x)    -- get one byte of data
   serial_data = x          -- send it to the serial port
end loop
fat32_small_file_close()       -- close the file

;   -- WRITE TO THE END OF THE FILE
;   --
;   -- calculate the next available sector
;   var dword address = (fat32_small_file_size / 512) + 1
;   fat32_small_file_open(address)                     -- open the file
;   for 200 using new_file_size_count loop             -- loop 200 times
;      fat32_small_file_write("K") -- write each data byte
;   end loop
;   fat32_small_file_close() -- close the file
;
;   -- set the new file size
;   fat32_small_set_file_size((address * 512) + new_file_size_count)
;
;   print_crlf(serial_data)
;   print_crlf(serial_data)
;
;   -- READ THE ENTIRE FILE AGAIN
;   fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
;   for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
;      fat32_small_file_read(x)    -- get one byte of data
;      serial_data = x          -- send it to the serial port
;   end loop
;   fat32_small_file_close()       -- close the file

Generated by JALlib CHM Help System | Source: fat32_small.jal


fat32_small_file_read - JALlib Procedures Help

fat32_small_file_read JALLIB PROCEDURE

Signature

procedure fat32_small_file_read(byte out data) is

Description

Read data from the file

Include

To use this procedure, include the library:

include fat32_small

Parameters

  • data - byte out

Return Value

None

Example

From sample file: 18f4620_fat32_small_sd_card.jal

-- Title: FAT32-small sample for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example reads files & folders from a fat32 formatted storage
--              device using the fat32-small library. This small version only
--              supports the first partition, and only one file.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- Notes:
-- 1. First format your device with fat32 before using this library.
-- 2. Do not put other files onto the storage device. This sample will
--    overwrite and erase existing files on the storage device because
--    only one file is supported, and no fragments are supported.
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- setup fat32 --
const FAT32_SMALL_SMALL_VERSION  = TRUE          -- use the small version of fat32
const FAT32_SMALL_VOL_ID[11]     = "Vol_ID     " -- 11 byte volume id (name of partition)
const FAT32_SMALL_FILE_NAME[8]   = "DATA    "    -- 8 byte file name (name of the 1 file allowed)
const FAT32_SMALL_FILE_EXT[3]    = "DAT"         -- 3 byte file extension (extension of the 1 file allowed)
const FAT32_SMALL_MAX_FILE_SIZE  = 50000        -- max file size
const byte FAT32_SMALL_ATTRIBUTE = 0x20          -- the file attributes
--
include fat32_small   -- include small fat32 library

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   print_crlf(serial_data)
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port.
separator()             -- send "----" via serial port
print_crlf(serial_data)
var byte start_string[] = "FAT32 SMALL - SAMPLE STARTED"
print_string(serial_data,start_string)
separator()             -- send "----" via serial port
print_crlf(serial_data)

fat32_small_init() -- initalize data media

-- WRITE TO THE FILE
var dword new_file_size_count -- count how many bytes you have written
-- open the file, at file sector number 0 (the beginning of the file)
fat32_small_file_open(0)
for 3000 using new_file_size_count loop             -- loop 200 times
   fat32_small_file_write("J") -- write each data byte
end loop
fat32_small_file_close() -- close the file

-- update the file size on the storage device
fat32_small_set_file_size(new_file_size_count)

-- READ THE FILE
var byte x
fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
   fat32_small_file_read(x)    -- get one byte of data
   serial_data = x          -- send it to the serial port
end loop
fat32_small_file_close()       -- close the file

;   -- WRITE TO THE END OF THE FILE
;   --
;   -- calculate the next available sector
;   var dword address = (fat32_small_file_size / 512) + 1
;   fat32_small_file_open(address)                     -- open the file
;   for 200 using new_file_size_count loop             -- loop 200 times
;      fat32_small_file_write("K") -- write each data byte
;   end loop
;   fat32_small_file_close() -- close the file
;
;   -- set the new file size
;   fat32_small_set_file_size((address * 512) + new_file_size_count)
;
;   print_crlf(serial_data)
;   print_crlf(serial_data)
;
;   -- READ THE ENTIRE FILE AGAIN
;   fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
;   for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
;      fat32_small_file_read(x)    -- get one byte of data
;      serial_data = x          -- send it to the serial port
;   end loop
;   fat32_small_file_close()       -- close the file

Generated by JALlib CHM Help System | Source: fat32_small.jal


fat32_small_file_write - JALlib Procedures Help

fat32_small_file_write JALLIB PROCEDURE

Signature

procedure fat32_small_file_write(byte in data) is

Description

Write data to the file

Include

To use this procedure, include the library:

include fat32_small

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f4620_fat32_small_sd_card.jal

-- Title: FAT32-small sample for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example reads files & folders from a fat32 formatted storage
--              device using the fat32-small library. This small version only
--              supports the first partition, and only one file.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- Notes:
-- 1. First format your device with fat32 before using this library.
-- 2. Do not put other files onto the storage device. This sample will
--    overwrite and erase existing files on the storage device because
--    only one file is supported, and no fragments are supported.
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- setup fat32 --
const FAT32_SMALL_SMALL_VERSION  = TRUE          -- use the small version of fat32
const FAT32_SMALL_VOL_ID[11]     = "Vol_ID     " -- 11 byte volume id (name of partition)
const FAT32_SMALL_FILE_NAME[8]   = "DATA    "    -- 8 byte file name (name of the 1 file allowed)
const FAT32_SMALL_FILE_EXT[3]    = "DAT"         -- 3 byte file extension (extension of the 1 file allowed)
const FAT32_SMALL_MAX_FILE_SIZE  = 50000        -- max file size
const byte FAT32_SMALL_ATTRIBUTE = 0x20          -- the file attributes
--
include fat32_small   -- include small fat32 library

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   print_crlf(serial_data)
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port.
separator()             -- send "----" via serial port
print_crlf(serial_data)
var byte start_string[] = "FAT32 SMALL - SAMPLE STARTED"
print_string(serial_data,start_string)
separator()             -- send "----" via serial port
print_crlf(serial_data)

fat32_small_init() -- initalize data media

-- WRITE TO THE FILE
var dword new_file_size_count -- count how many bytes you have written
-- open the file, at file sector number 0 (the beginning of the file)
fat32_small_file_open(0)
for 3000 using new_file_size_count loop             -- loop 200 times
   fat32_small_file_write("J") -- write each data byte
end loop
fat32_small_file_close() -- close the file

-- update the file size on the storage device
fat32_small_set_file_size(new_file_size_count)

-- READ THE FILE
var byte x
fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
   fat32_small_file_read(x)    -- get one byte of data
   serial_data = x          -- send it to the serial port
end loop
fat32_small_file_close()       -- close the file

;   -- WRITE TO THE END OF THE FILE
;   --
;   -- calculate the next available sector
;   var dword address = (fat32_small_file_size / 512) + 1
;   fat32_small_file_open(address)                     -- open the file
;   for 200 using new_file_size_count loop             -- loop 200 times
;      fat32_small_file_write("K") -- write each data byte
;   end loop
;   fat32_small_file_close() -- close the file
;
;   -- set the new file size
;   fat32_small_set_file_size((address * 512) + new_file_size_count)
;
;   print_crlf(serial_data)
;   print_crlf(serial_data)
;
;   -- READ THE ENTIRE FILE AGAIN
;   fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
;   for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
;      fat32_small_file_read(x)    -- get one byte of data
;      serial_data = x          -- send it to the serial port
;   end loop
;   fat32_small_file_close()       -- close the file

Generated by JALlib CHM Help System | Source: fat32_small.jal


fat32_small_init - JALlib Procedures Help

fat32_small_init JALLIB PROCEDURE

Signature

procedure fat32_small_init() is

Description

initalize fat32

Include

To use this procedure, include the library:

include fat32_small

Parameters

None

Return Value

None

Example

From sample file: 18f4620_fat32_small_sd_card.jal

-- Title: FAT32-small sample for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example reads files & folders from a fat32 formatted storage
--              device using the fat32-small library. This small version only
--              supports the first partition, and only one file.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- Notes:
-- 1. First format your device with fat32 before using this library.
-- 2. Do not put other files onto the storage device. This sample will
--    overwrite and erase existing files on the storage device because
--    only one file is supported, and no fragments are supported.
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- setup fat32 --
const FAT32_SMALL_SMALL_VERSION  = TRUE          -- use the small version of fat32
const FAT32_SMALL_VOL_ID[11]     = "Vol_ID     " -- 11 byte volume id (name of partition)
const FAT32_SMALL_FILE_NAME[8]   = "DATA    "    -- 8 byte file name (name of the 1 file allowed)
const FAT32_SMALL_FILE_EXT[3]    = "DAT"         -- 3 byte file extension (extension of the 1 file allowed)
const FAT32_SMALL_MAX_FILE_SIZE  = 50000        -- max file size
const byte FAT32_SMALL_ATTRIBUTE = 0x20          -- the file attributes
--
include fat32_small   -- include small fat32 library

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   print_crlf(serial_data)
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port.
separator()             -- send "----" via serial port
print_crlf(serial_data)
var byte start_string[] = "FAT32 SMALL - SAMPLE STARTED"
print_string(serial_data,start_string)
separator()             -- send "----" via serial port
print_crlf(serial_data)

fat32_small_init() -- initalize data media

-- WRITE TO THE FILE
var dword new_file_size_count -- count how many bytes you have written
-- open the file, at file sector number 0 (the beginning of the file)
fat32_small_file_open(0)
for 3000 using new_file_size_count loop             -- loop 200 times
   fat32_small_file_write("J") -- write each data byte
end loop
fat32_small_file_close() -- close the file

-- update the file size on the storage device
fat32_small_set_file_size(new_file_size_count)

-- READ THE FILE
var byte x
fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
   fat32_small_file_read(x)    -- get one byte of data
   serial_data = x          -- send it to the serial port
end loop
fat32_small_file_close()       -- close the file

;   -- WRITE TO THE END OF THE FILE
;   --
;   -- calculate the next available sector
;   var dword address = (fat32_small_file_size / 512) + 1
;   fat32_small_file_open(address)                     -- open the file
;   for 200 using new_file_size_count loop             -- loop 200 times
;      fat32_small_file_write("K") -- write each data byte
;   end loop
;   fat32_small_file_close() -- close the file
;
;   -- set the new file size
;   fat32_small_set_file_size((address * 512) + new_file_size_count)
;
;   print_crlf(serial_data)
;   print_crlf(serial_data)
;
;   -- READ THE ENTIRE FILE AGAIN
;   fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
;   for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
;      fat32_small_file_read(x)    -- get one byte of data
;      serial_data = x          -- send it to the serial port
;   end loop
;   fat32_small_file_close()       -- close the file

Generated by JALlib CHM Help System | Source: fat32_small.jal


fat32_small_set_file_size - JALlib Procedures Help

fat32_small_set_file_size JALLIB PROCEDURE

Signature

procedure fat32_small_set_file_size(dword in file_size) is

Description

Set the size of the file.

Include

To use this procedure, include the library:

include fat32_small

Parameters

  • file_size - dword in

Return Value

None

Example

From sample file: 18f4620_fat32_small_sd_card.jal

-- Title: FAT32-small sample for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example reads files & folders from a fat32 formatted storage
--              device using the fat32-small library. This small version only
--              supports the first partition, and only one file.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- Notes:
-- 1. First format your device with fat32 before using this library.
-- 2. Do not put other files onto the storage device. This sample will
--    overwrite and erase existing files on the storage device because
--    only one file is supported, and no fragments are supported.
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- setup fat32 --
const FAT32_SMALL_SMALL_VERSION  = TRUE          -- use the small version of fat32
const FAT32_SMALL_VOL_ID[11]     = "Vol_ID     " -- 11 byte volume id (name of partition)
const FAT32_SMALL_FILE_NAME[8]   = "DATA    "    -- 8 byte file name (name of the 1 file allowed)
const FAT32_SMALL_FILE_EXT[3]    = "DAT"         -- 3 byte file extension (extension of the 1 file allowed)
const FAT32_SMALL_MAX_FILE_SIZE  = 50000        -- max file size
const byte FAT32_SMALL_ATTRIBUTE = 0x20          -- the file attributes
--
include fat32_small   -- include small fat32 library

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   print_crlf(serial_data)
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port.
separator()             -- send "----" via serial port
print_crlf(serial_data)
var byte start_string[] = "FAT32 SMALL - SAMPLE STARTED"
print_string(serial_data,start_string)
separator()             -- send "----" via serial port
print_crlf(serial_data)

fat32_small_init() -- initalize data media

-- WRITE TO THE FILE
var dword new_file_size_count -- count how many bytes you have written
-- open the file, at file sector number 0 (the beginning of the file)
fat32_small_file_open(0)
for 3000 using new_file_size_count loop             -- loop 200 times
   fat32_small_file_write("J") -- write each data byte
end loop
fat32_small_file_close() -- close the file

-- update the file size on the storage device
fat32_small_set_file_size(new_file_size_count)

-- READ THE FILE
var byte x
fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
   fat32_small_file_read(x)    -- get one byte of data
   serial_data = x          -- send it to the serial port
end loop
fat32_small_file_close()       -- close the file

;   -- WRITE TO THE END OF THE FILE
;   --
;   -- calculate the next available sector
;   var dword address = (fat32_small_file_size / 512) + 1
;   fat32_small_file_open(address)                     -- open the file
;   for 200 using new_file_size_count loop             -- loop 200 times
;      fat32_small_file_write("K") -- write each data byte
;   end loop
;   fat32_small_file_close() -- close the file
;
;   -- set the new file size
;   fat32_small_set_file_size((address * 512) + new_file_size_count)
;
;   print_crlf(serial_data)
;   print_crlf(serial_data)
;
;   -- READ THE ENTIRE FILE AGAIN
;   fat32_small_file_open(0)       -- open the file, at file sector 0 (the beginning)
;   for fat32_small_file_size loop -- read the entire file with fat32_small_file_size
;      fat32_small_file_read(x)    -- get one byte of data
;      serial_data = x          -- send it to the serial port
;   end loop
;   fat32_small_file_close()       -- close the file

Generated by JALlib CHM Help System | Source: fat32_small.jal


fat32_start_file_read - JALlib Procedures Help

fat32_start_file_read JALLIB PROCEDURE

Signature

procedure fat32_start_file_read() is

Description

Start reading a file

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_start_file_write - JALlib Procedures Help

fat32_start_file_write JALLIB PROCEDURE

Signature

procedure fat32_start_file_write() is

Description

Start writing to a file

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_write_file_sector - JALlib Procedures Help

fat32_write_file_sector JALLIB PROCEDURE

Signature

procedure fat32_write_file_sector() is

Description

write one sector to a file starting at the beginning of the file.
auto increments to next sector in file. fragmented files work.
requires: fat32_start_file_write(fat32_file_location), fat32_stop_file_write
faster then fat32_write_file_sector_number() procedure

Include

To use this procedure, include the library:

include fat32

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


fat32_write_file_sector_number - JALlib Procedures Help

fat32_write_file_sector_number JALLIB PROCEDURE

Signature

procedure fat32_write_file_sector_number(dword in file_sector_number) is

Description

writes selected sector to a file. fragmented files work.
slower then fat32_write_file_sector() procedure, but user friendly.

Include

To use this procedure, include the library:

include fat32

Parameters

  • file_sector_number - dword in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: fat32.jal


flash_data.jal - JALLIB Library Documentation

flash_data.jal JALLIB LIBRARY

Title

Flash memory library for 18FxxJyy series

Author

Rob Hamerling, Copyright (c) 2012..2012, all rights reserved., Adapted-by:

Compiler

2.4o

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

Procedures and fuctions to read/erase/write flash (code) memory of 18FxxJxx.
.
Since erase of flash memory is required before writes and 1024 bytes are
erased at a time with these PICs, a 1 KB block of flash must be reserved,
and it must be on a 1KB boundary (10 LSbits of address must be zero).
Limitations to choose a proper address are:
- The program is located in low memory
- The highest bytes of flash memory contain the configuration bits
of many 18F PICs, including the J-series
So both the lowest and the highest 1KB of code memory are not usable for
the purpose of storing data.
The one but highest 1K block of code memory seems the only choice!
Beware that the program is not so big that it occupies this address.
The location is also PIC dependent, so when changing PIC change the address!
.
Since flash memory is written 64 bytes at a time the block of data memory to
be saved in flash memory must be a multiple of 64 bytes. The way to do this
is by declaring an array of bytes (a multiple of 64) and declare the variables
as overlay of this array.
.
Before including this library you have to specify:
.
- The address of the block of flash memory where to save your data, e.g.:
.
const byte*3 FLASH_RESERVED = 0x00F800 -- one but highest 1KB block
-- for a PIC with 64KB flash
.
- An array named 'flash_data' containing the data
you want to save to and restore from flash memory, e.g.:
.
var byte flash_data[128] -- block to save in flash memory
.
This array may be smaller than 1KB, but not larger!
(The JALV2 compiler doesn't support arrays larger than 256 bytes)!
.
Available procedures/functions:
flash_erase_block() - erase the 1KB block of flash memory
flash_read_word() - read a word (2 bytes) of flash memory
flash_restore_block() - restore the block of memory from flash memory
flash_save_block() - save the block of data memory to flash memory

Notes

Limitations of this library:
- Only PICs of type 18FxxJyy are supported (and only some are tested).
- Maximum size of data block to be saved is 1024 bytes.
=====================================================================

---------- Some sanity checks ----------------

-------------------------------------------------------
Erase row (1KB) of flash memory
Arguments: - none
Returns: - nothing
- The reserved block of 1KB flash memory is erased
-------------------------------------------------------

Routines

  • flash_erase_block - Procedure
  • flash_read_word - Function returns word
  • flash_restore_block - Procedure
  • flash_save_block - Procedure


flash_read_word - JALlib Procedures Help

flash_read_word JALLIB FUNCTION

Signature

function flash_read_word(word in offset) return word is

Description

Read word of flash memory
Arguments: - offset (in number of bytes) of a word in the
reserved block of flash memory
Returns: - contents of the addressed word in flash memory
Notes: - The first word of the reserved block has offset 0.
To read it use 'flash_read_word(0)'
- This function is especially useful to check if the
flash memory block was ever written before when
the first word contains some sort of identification.

Include

To use this procedure, include the library:

include flash_data

Parameters

  • offset - word in

Return Value

word - - contents of the addressed word in flash memory

Example

From sample file: 18f26j11_flash_data.jal

-- --------------------------------------------------------------------
-- Title: How to use flash memory of an 18f26j11 for variable data
--
-- Author: Rob Hamerling, Copyright (c) 2012..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Example of how to use flash (code) memory to save variable data over
-- reset/power-off cycles of PICs without EEPROM.
-- In this sample a counter is incremented at every start of the program
-- and the new value is saved in flash memory.
-- The current value of the counter is shown by the number of blinks of a led.
-- This shows the number of resets since the time the program was loaded.
-- .
-- A 'signature' is the first part of the overlay. This shows to the program
-- that flash memory was ever written (first time issue). Only when this
-- signature is found in the first few bytes of the reserved block of flash
-- memory the data block may be restored.
-- In this sample the signature is "RobH".
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- - This sample shows the use of flash_data library
--
-- =====================================================================

include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intosc 8 MHz

-- ---------- configuration bits settings -------------------------
pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         DISABLED               -- no timer1 oscillator
pragma target LPT1OSC       HIGH_POWER             -- high power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- no osc switch over
pragma target WDTPS         P64                    -- watchdog timeout about 1/4 sec
pragma target DSWDTOSC      INTOSC                 -- for deep sleep WDT
pragma target RTCOSC        INTOSC                 -- RTCC uses INT Osc
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

-- --------- JAL extensions --------------------

include  delay                                     -- delay support library

-- --------- block of data to be saved in flash (code) memory -----------------

const  byte*3  FLASH_RESERVED = 0x00F800           -- address of 1KB flash memory
                                                   -- to save data

var  byte      flash_data[64]                      -- block of data to be saved in and
                                                   -- restored from flash memory

include flash_data                                 -- the library

-- --- local function prototypes ----------------------------------------------

procedure  setup_pic()

-- ----------------------------------------------------------------------------

var  byte      signature[4]    at flash_data[0]  = "RobH"     -- flash block identification
var  word      reset_counter   at flash_data[4]  = 0          -- initial 'reset' value
var  byte      filler[8]       at flash_data[6]  = "ABCDEFGH" -- dummy for read back check

alias  LED is pin_B1                               -- visual indication of reset-counter

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

setup_pic()                                        -- init PIC

pin_B1_direction = OUTPUT                          -- make LED-pin output

LED = OFF                                          -- initial status of LED

-- check if signature is present in flash memory
-- if yes replace the contents of the data block by the contents of the flash block
if ( (flash_read_word(0) == 0x6F52)  &             -- "Ro" 1st part of flash-ID found
     (flash_read_word(2) == 0x4862) ) then         -- "bH" 2nd part of flash-ID found
   flash_restore_block()                           -- flash-ID found: restore block
end if

reset_counter = reset_counter + 1                  -- increment counter
for reset_counter loop                             -- show value of counter
   LED = ON
   delay_100ms(2)
   LED = OFF
   delay_100ms(2)
end loop

flash_save_block()                                 -- save updated block to flash memory

forever loop
   LED = OFF
end loop

-- -------------------------------------------------------
--  Perform basic PIC Setup
-- -------------------------------------------------------
procedure  setup_pic() is

   enable_digital_io()                             -- disable all analog I/O

   INTCON         = 0b0000_0000                    -- no interrupts

   OSCCON_IRCF    = 0b111                          -- INTOSC at 8 MHz
   OSCCON_SCS     = 0b00                           -- primary clock source INTOSC
   OSCCON_IDLEN   = 0                              -- for sleep (not idle) mode

   REFOCON_ROON   = FALSE                          -- no oscillator output

   WDTCON         = 0b0000_0000                    -- disable watchdog
   DSCONH_DSEN    = FALSE                          -- no deep sleep mode

   T1CON          = 0b0000_0000                    -- Tmr1 off
   T2CON          = 0b0000_0000                    -- Tmr2 off

   portA          = 0b0000_0000                    -- )
   portB          = 0b0000_0000                    -- ) init ports
   portC          = 0b0000_0000                    -- )

   portA_direction = ALL_OUTPUT                    -- )
   portB_direction = ALL_OUTPUT                    -- ) pin directions
   portC_direction = ALL_OUTPUT                    -- )

end procedure

Generated by JALlib CHM Help System | Source: flash_data.jal


flash_restore_block - JALlib Procedures Help

flash_restore_block JALLIB PROCEDURE

Signature

procedure flash_restore_block() is

Description

Copy block of flash memory to block of data memory
Arguments: none
Returns: nothing
Notes: The whole array 'flash_data' is restored

Include

To use this procedure, include the library:

include flash_data

Parameters

None

Return Value

None

Example

From sample file: 18f26j11_flash_data.jal

-- --------------------------------------------------------------------
-- Title: How to use flash memory of an 18f26j11 for variable data
--
-- Author: Rob Hamerling, Copyright (c) 2012..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Example of how to use flash (code) memory to save variable data over
-- reset/power-off cycles of PICs without EEPROM.
-- In this sample a counter is incremented at every start of the program
-- and the new value is saved in flash memory.
-- The current value of the counter is shown by the number of blinks of a led.
-- This shows the number of resets since the time the program was loaded.
-- .
-- A 'signature' is the first part of the overlay. This shows to the program
-- that flash memory was ever written (first time issue). Only when this
-- signature is found in the first few bytes of the reserved block of flash
-- memory the data block may be restored.
-- In this sample the signature is "RobH".
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- - This sample shows the use of flash_data library
--
-- =====================================================================

include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intosc 8 MHz

-- ---------- configuration bits settings -------------------------
pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         DISABLED               -- no timer1 oscillator
pragma target LPT1OSC       HIGH_POWER             -- high power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- no osc switch over
pragma target WDTPS         P64                    -- watchdog timeout about 1/4 sec
pragma target DSWDTOSC      INTOSC                 -- for deep sleep WDT
pragma target RTCOSC        INTOSC                 -- RTCC uses INT Osc
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

-- --------- JAL extensions --------------------

include  delay                                     -- delay support library

-- --------- block of data to be saved in flash (code) memory -----------------

const  byte*3  FLASH_RESERVED = 0x00F800           -- address of 1KB flash memory
                                                   -- to save data

var  byte      flash_data[64]                      -- block of data to be saved in and
                                                   -- restored from flash memory

include flash_data                                 -- the library

-- --- local function prototypes ----------------------------------------------

procedure  setup_pic()

-- ----------------------------------------------------------------------------

var  byte      signature[4]    at flash_data[0]  = "RobH"     -- flash block identification
var  word      reset_counter   at flash_data[4]  = 0          -- initial 'reset' value
var  byte      filler[8]       at flash_data[6]  = "ABCDEFGH" -- dummy for read back check

alias  LED is pin_B1                               -- visual indication of reset-counter

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

setup_pic()                                        -- init PIC

pin_B1_direction = OUTPUT                          -- make LED-pin output

LED = OFF                                          -- initial status of LED

-- check if signature is present in flash memory
-- if yes replace the contents of the data block by the contents of the flash block
if ( (flash_read_word(0) == 0x6F52)  &             -- "Ro" 1st part of flash-ID found
     (flash_read_word(2) == 0x4862) ) then         -- "bH" 2nd part of flash-ID found
   flash_restore_block()                           -- flash-ID found: restore block
end if

reset_counter = reset_counter + 1                  -- increment counter
for reset_counter loop                             -- show value of counter
   LED = ON
   delay_100ms(2)
   LED = OFF
   delay_100ms(2)
end loop

flash_save_block()                                 -- save updated block to flash memory

forever loop
   LED = OFF
end loop

-- -------------------------------------------------------
--  Perform basic PIC Setup
-- -------------------------------------------------------
procedure  setup_pic() is

   enable_digital_io()                             -- disable all analog I/O

   INTCON         = 0b0000_0000                    -- no interrupts

   OSCCON_IRCF    = 0b111                          -- INTOSC at 8 MHz
   OSCCON_SCS     = 0b00                           -- primary clock source INTOSC
   OSCCON_IDLEN   = 0                              -- for sleep (not idle) mode

   REFOCON_ROON   = FALSE                          -- no oscillator output

   WDTCON         = 0b0000_0000                    -- disable watchdog
   DSCONH_DSEN    = FALSE                          -- no deep sleep mode

   T1CON          = 0b0000_0000                    -- Tmr1 off
   T2CON          = 0b0000_0000                    -- Tmr2 off

   portA          = 0b0000_0000                    -- )
   portB          = 0b0000_0000                    -- ) init ports
   portC          = 0b0000_0000                    -- )

   portA_direction = ALL_OUTPUT                    -- )
   portB_direction = ALL_OUTPUT                    -- ) pin directions
   portC_direction = ALL_OUTPUT                    -- )

end procedure

Generated by JALlib CHM Help System | Source: flash_data.jal


flash_save_block - JALlib Procedures Help

flash_save_block JALLIB PROCEDURE

Signature

procedure flash_save_block() is

Description

Save block of data memory to flash memory
Arguments: - none
Returns: - nothing
Notes: The whole array 'flash_data' is saved

Include

To use this procedure, include the library:

include flash_data

Parameters

None

Return Value

None

Example

From sample file: 18f26j11_flash_data.jal

-- --------------------------------------------------------------------
-- Title: How to use flash memory of an 18f26j11 for variable data
--
-- Author: Rob Hamerling, Copyright (c) 2012..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Example of how to use flash (code) memory to save variable data over
-- reset/power-off cycles of PICs without EEPROM.
-- In this sample a counter is incremented at every start of the program
-- and the new value is saved in flash memory.
-- The current value of the counter is shown by the number of blinks of a led.
-- This shows the number of resets since the time the program was loaded.
-- .
-- A 'signature' is the first part of the overlay. This shows to the program
-- that flash memory was ever written (first time issue). Only when this
-- signature is found in the first few bytes of the reserved block of flash
-- memory the data block may be restored.
-- In this sample the signature is "RobH".
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- - This sample shows the use of flash_data library
--
-- =====================================================================

include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intosc 8 MHz

-- ---------- configuration bits settings -------------------------
pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         DISABLED               -- no timer1 oscillator
pragma target LPT1OSC       HIGH_POWER             -- high power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- no osc switch over
pragma target WDTPS         P64                    -- watchdog timeout about 1/4 sec
pragma target DSWDTOSC      INTOSC                 -- for deep sleep WDT
pragma target RTCOSC        INTOSC                 -- RTCC uses INT Osc
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

-- --------- JAL extensions --------------------

include  delay                                     -- delay support library

-- --------- block of data to be saved in flash (code) memory -----------------

const  byte*3  FLASH_RESERVED = 0x00F800           -- address of 1KB flash memory
                                                   -- to save data

var  byte      flash_data[64]                      -- block of data to be saved in and
                                                   -- restored from flash memory

include flash_data                                 -- the library

-- --- local function prototypes ----------------------------------------------

procedure  setup_pic()

-- ----------------------------------------------------------------------------

var  byte      signature[4]    at flash_data[0]  = "RobH"     -- flash block identification
var  word      reset_counter   at flash_data[4]  = 0          -- initial 'reset' value
var  byte      filler[8]       at flash_data[6]  = "ABCDEFGH" -- dummy for read back check

alias  LED is pin_B1                               -- visual indication of reset-counter

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

setup_pic()                                        -- init PIC

pin_B1_direction = OUTPUT                          -- make LED-pin output

LED = OFF                                          -- initial status of LED

-- check if signature is present in flash memory
-- if yes replace the contents of the data block by the contents of the flash block
if ( (flash_read_word(0) == 0x6F52)  &             -- "Ro" 1st part of flash-ID found
     (flash_read_word(2) == 0x4862) ) then         -- "bH" 2nd part of flash-ID found
   flash_restore_block()                           -- flash-ID found: restore block
end if

reset_counter = reset_counter + 1                  -- increment counter
for reset_counter loop                             -- show value of counter
   LED = ON
   delay_100ms(2)
   LED = OFF
   delay_100ms(2)
end loop

flash_save_block()                                 -- save updated block to flash memory

forever loop
   LED = OFF
end loop

-- -------------------------------------------------------
--  Perform basic PIC Setup
-- -------------------------------------------------------
procedure  setup_pic() is

   enable_digital_io()                             -- disable all analog I/O

   INTCON         = 0b0000_0000                    -- no interrupts

   OSCCON_IRCF    = 0b111                          -- INTOSC at 8 MHz
   OSCCON_SCS     = 0b00                           -- primary clock source INTOSC
   OSCCON_IDLEN   = 0                              -- for sleep (not idle) mode

   REFOCON_ROON   = FALSE                          -- no oscillator output

   WDTCON         = 0b0000_0000                    -- disable watchdog
   DSCONH_DSEN    = FALSE                          -- no deep sleep mode

   T1CON          = 0b0000_0000                    -- Tmr1 off
   T2CON          = 0b0000_0000                    -- Tmr2 off

   portA          = 0b0000_0000                    -- )
   portB          = 0b0000_0000                    -- ) init ports
   portC          = 0b0000_0000                    -- )

   portA_direction = ALL_OUTPUT                    -- )
   portB_direction = ALL_OUTPUT                    -- ) pin directions
   portC_direction = ALL_OUTPUT                    -- )

end procedure

Generated by JALlib CHM Help System | Source: flash_data.jal


flash_sst25vf.jal - JALLIB Library Documentation

flash_sst25vf.jal JALLIB LIBRARY

Title

External SPI bus 1...128Mb Flash from Microchip/SST,

Author

Urmas Joeleht (c) 2014, 2015, all rights reserved., Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Microchip (SST) 1...128 Mbit serial flash chip.
Functions and procedures:
sst25vf_init()
sst25vf_read_byte()
sst25vf_read_word()
sst25vf_read_dword()
sst25vf_rd_status()
sst25vf_read_id()
sst25vf_read_jedec_id()
sst25vf_chip_ready()
sst25vf_write_byte()
sst25vf_write_word()
sst25vf_write_dword()
sst25vf_erase_4kb_sector()
sst25vf_erase_32kb_block()
sst25vf_erase_64kb_block()

Notes

User must take care
in program about max addresses of chip
Size: Max mem address:
1M: 0x01FFFF (no erase_64 and get jedec_id functions)
2M: 0x03FFFF
4M: 0x07FFFF
8M: 0x0FFFFF Tested!
16M: 0x1FFFFF Tested!
32M: 0x3FFFFF
64M: 0x7FFFFF
128M: 0xFFFFFF
Example declaration:
alias sst25vf_cs is pin_A7 -- chip select/slave select pin
alias sst25vf_cs_direction is pin_a7_direction
sst25vf_cs_direction = output
sst25vf_cs = high
--
If several SPI devices used, then:
const bit SST25VF_ALWAYS_SET_SPI_MODE = TRUE
alias sst25vf_force_spi_mode is spi_master_hw_set_mode_00
or
alias sst25vf_force_spi_mode is spi_master_hw2_set_mode_00
include sst25vf
var byte sst25vf_settings
sst25vf_init()
Example file:
18f27j53_pps_sst25vf.jal
ToDo:
Continuous read, write
Read in high (80Mhz) speed mode
Block protection
--------------------------------------------------------------------------------
Device Operation Instructions from datasheet:
--------------------------------------------------------------------------------

Sources

http://ww1.microchip.com/downloads/en/DeviceDoc/20005045B.pdf (8Mb serial Flash)
http://ww1.microchip.com/downloads/en/DeviceDoc/25071A.pdf (32Mb serial Flash)
23K256 sram library. Author: Matthew Schinkel, adapted-by: Sebastien Lelong

Constants and Variables

SST25VF_READ_COMM - const byte = 0x03
SST25VF_READ_HS_COMM - const byte = 0x0B
SST25VF_4K_SECTOR_ERASE_COMM - const byte = 0x20
SST25VF_32K_SECTOR_ERASE_COMM - const byte = 0x52
SST25VF_64K_SECTOR_ERASE_COMM - const byte = 0xD8
SST25VF_CHIP_ERASE_COMM - const byte = 0x60
SST25VF_BYTE_PROGRAM_COMM - const byte = 0x02
SST25VF_AAI_W_PROGRAM_COMM - const byte = 0xAD
SST25VF_READ_STATUS_COMM - const byte = 0x05
SST25VF_ENABLE_WR_STATUS_COMM - const byte = 0x50
SST25VF_WRITE_STATUS_COMM - const byte = 0x01
SST25VF_WRITE_ENABLE_COMM - const byte = 0x06
SST25VF_WRITE_DISABLE_COMM - const byte = 0x04
SST25VF_READ_ID_COMM - const byte = 0x90
SST25VF_READ_JEDEC_ID_COMM - const byte = 0x9F
SST25VF_EBSY_COMM - const byte = 0x70 -- Enable SO as an output RY/BY# status during AAI programming
Enable SO as an output RY/BY# status during AAI programming
SST25VF_DBSY_COMM - const byte = 0x80 -- Disable SO as an output RY/BY# status during AAI programming
Disable SO as an output RY/BY# status during AAI programming

Routines

  • sst25vf_chip_erase - Procedure
  • sst25vf_chip_ready - Function returns bit
  • sst25vf_erase_32kb_block - Procedure
  • sst25vf_erase_4kb_sector - Procedure
  • sst25vf_erase_64kb_block - Procedure
  • sst25vf_init - Procedure
  • sst25vf_rd_status - Function returns byte
  • sst25vf_read_byte - Function returns byte
  • sst25vf_read_dword - Function returns dword
  • sst25vf_read_id - Procedure
  • sst25vf_read_jedec_id - Procedure
  • sst25vf_read_word - Function returns word
  • sst25vf_wr_status - Procedure
  • sst25vf_write_byte - Procedure
  • sst25vf_write_dword - Procedure
  • sst25vf_write_word - Procedure


Floating Point Operations - JAL Language Syntax Reference

Floating Point Operations JALV2 SYNTAX

Description

Most floating point operations are done via function calls because of the size of the code generated, so at least one stack entry will be used per operation. For multiplication and division, two stack entries are required because these rely on the integer routines. Operations that do not require a function call include: multiplication or division by a power of 2, assignment from a constant.

Generated by JAL Syntax Documentation System | Source: DITA


Flow Control - JAL Language Syntax Reference

Flow Control JALV2 SYNTAX

Description

Generated by JAL Syntax Documentation System | Source: DITA


FOR - JAL Language Syntax Reference

FOR JALV2 SYNTAX

Syntax

FOR expr
    [ USING var ]
    LOOP
    statement_block
    [ EXIT LOOP ]
END LOOP

Description

statement_block [ EXIT LOOP ] END LOOP statement_block is executed expr times. If USING varis deﬁned, the index is kept in var, beginning with zero and incrementing towards expr. Ifvaris not large enough to hold expr, a warning is generated. If [EXIT LOOP] is used, the loop is immediately exited.

Notes

On normal exit, varis equal to expr. After, ‘EXIT LOOP,’ varholds whatever value it had at the beginning of the loop. November 2010 -- a minor enhancement has been made at the request of the users. If expr is acexpr and is one larger than varcan hold, the loop will be exited when varrolls over to zero. In this case, on exit varwill be zero.

Example

VAR BYTE n
FOR 256 USING n LOOP
...
END LOOP
15

Generated by JAL Syntax Documentation System | Source: DITA


format.jal - JALLIB Library Documentation

format.jal JALLIB LIBRARY

Title

Writes formatted values to output device

Author

Stef Mientki, Copyright (c) 2002 .. 2006, all rights reserved., Adapted-by: Joep Suijs, Albert Faber, Eur van Andel

Compiler

>=2.2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Outputs variables to output device.
Writes formatted signed/unsiged bytes/words to the specified output device.
Decimal (with fraction), Hex and Time formats available.
--
Example:
--
var sword BHL = -684
--
; send the signed word to the LCD display
; total field width 6 chars, including sign and decimal
; with 2 digits behind the decimal point
format_sword_dec(LCD_char,BHL,6,2)
--
; and now send the same signed word to the serial port
format_sword_dec(Serial_HW_data,BHL,6,2)

Notes

-----------------------------------------------------------------------------
global vars
-----------------------------------------------------------------------------

Constants and Variables

i - var byte

Routines

  • _write_digit - Procedure
  • _write_real_digit - Procedure
  • format_byte_dec - Procedure
  • format_byte_hex - Procedure
  • format_dword_dec - Procedure
  • format_dword_hex - Procedure
  • format_sbyte_dec - Procedure
  • format_sdword_dec - Procedure
  • format_sword_dec - Procedure
  • format_sword_dec_length - Procedure
  • format_time_hm - Procedure
  • format_time_hm_word - Procedure
  • format_time_hms - Procedure
  • format_word_dec - Procedure
  • format_word_hex - Procedure


format_byte_dec - JALlib Procedures Help

format_byte_dec JALLIB PROCEDURE

Signature

procedure format_byte_dec(volatile byte out device, byte in data, byte in n_tot, byte in n2) is

Description

writes decimal formatted byte to output device
the output can be specified as a fraction
n_tot = the total length (including sign and decimal point)
n2 = number of digits behind the point

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - byte in
  • n_tot - byte in
  • n2 - byte in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_byte_hex - JALlib Procedures Help

format_byte_hex JALLIB PROCEDURE

Signature

procedure format_byte_hex(volatile byte out device, byte in data) is

Description

writes hex formatted byte to output device

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - byte in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_dword_dec - JALlib Procedures Help

format_dword_dec JALLIB PROCEDURE

Signature

procedure format_dword_dec(volatile byte out device, dword in data, byte in n_tot, byte in n2) is

Description

writes decimal formatted dword to output device
the output can be specified as a fraction
n_tot = the total length (including sign and decimal point)
n2 = number of digits behind the point

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - dword in
  • n_tot - byte in
  • n2 - byte in

Return Value

None

Example

From sample file: 18f14k50_pll.jal

-- --------------------------------------------------------------------------------------------
-- Title: Example of the Motorola MC145156 PLL IC Lib using a PIC18F14K50
-- Author: Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved.
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Example of use of the PLL lib for the MC145156 IC. This example is for demostrating the
-- capabilities of jallib to manage the IC to revive an ancient VHF tranceiver from the
-- Yaesu house: an FT-23R
-- --
-- This tranceiver has afully functional system with the MC145156-2, the only thing you need to
-- know is how to wire the data, clock and enable wires
-- --
-- Other technical details: the IC has a 10.240 Mhz XTAL as the reference and is configured
-- to divide by 2048, that gives you a 5Khz reference clock and minimum step; the prescaler is a
-- common dual modulus 64/65 one.
--
-- Sources:
-- Thechnical Suplement for the Yaesy FT-23R in the internet, the datasheet of the MC145156-2,
-- datasheet of the prescaller and a old FT-23R
--
-- Notes:
-- * This file is maintained by hand!!!
-- * The goal of the lib is to make a simple VHF signal (RF) generator for VHF testing/repairing
--   this is only a demo of the capabilities.
-- * With my stock hardware the generator can cover ~116 to ~150 Mhz, with modifications & tweaking
--  (VCC increased from 5V to 8V and some adjustments) it can cover now from ~100 to 190 Mhz
--

-- device map
--             +VCC [1     20] GND
--               A5 [2     19] PGD
--               A4 [3     18] PGC
--        MCLR > A3 [4     17] +VUSB
--         DAT < C5 [5     16] C0 > d7  |
--         CLK < C4 [6     15] C1 > d6  | LCD 4 bits
--         ENB < C3 [7     14] C2 > d5  |
--               C6 [8     13] B4 > d4  |
--       abajo > C7 [9     12] B5 > RS  |
--      arriba > B7 [10    11] B6 > EN  |

-- include the device
include	18F14K50	-- target PICmicro
pragma target clock       16_000_000

-- fuses
WDTCON_SWDTEN               = OFF           -- WDT off
OSCCON_SCS                  = 0b10          -- Clock Source is internal
OSCCON_IRCF                 = 0b111         -- The internal Clock sources is set to 16 Mhz
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           INTOSC_NOCLKOUT
pragma target PLLEN         DISABLED
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          INTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

-- All digital
enable_digital_io()

-- ### LCD @ 4 bits (1x16)
const		byte		LCD_ROWS		= 1
const		byte		LCD_CHARS		= 16
alias		lcd_d4		is pin_B4
alias		lcd_d5		is pin_C2
alias		lcd_d6		is pin_C1
alias		lcd_d7		is pin_C0
alias		lcd_rs		is pin_B5
alias		lcd_en		is pin_B6
-- all lcd pins to output
pin_B4_direction		= output
pin_B5_direction		= output
pin_B6_direction		= output
pin_C0_direction		= output
pin_C1_direction		= output
pin_C2_direction		= output
-- loading and init...
include lcd_hd44780_4
lcd_init()

-- include delay lib
include delay

-- setup the format lib to show data to the lcd
include format
include print

-- pins for up/down with external pull-ups of 10k
-- alias
alias UP is pin_B7
alias DOWN is pin_C7
-- dir
pin_B7_direction	= input
pin_C7_direction	= input

-- pins for PLL, alias
alias pll_dat is pin_C5
alias pll_clk is pin_C4
alias pll_en is pin_C3
-- dirs
pin_C5_direction	= output
pin_C4_direction	= output
pin_C3_direction	= output

-- debounce
include debounce

-- variables
var dword freq = 145_000	-- the initial freq in Khzm this is a common Ham radio freq
-- debounce ones
var word updb = debounce_init(255)
var word dwdb = debounce_init(255)
-- temp
var word tword

-- setup of the PLL lib
const byte PLL_R = 5		-- 5 Khz of minimun step
const byte PLL_P = 64		-- prescaler simple value, in my case 64/65
include pll_mc145156
pll_init(freq)			-- set the initial freq to 145.000 Mhz as predefined before

procedure showit() is
   -- update the LCD
   lcd_cursor_position(0,0)
   print_string(lcd,"Freq ")
   format_dword_dec(lcd,freq,6,3)
   print_string(lcd," Mhz")
end procedure

-- WELCOME of the LCD
lcd_cursor_position(0,0)
--                0123456789abcdef
print_string(lcd,"PLL test FT-23R ")
-- delay
delay_1s(5)
--
lcd_cursor_position(0,0)
--                0123456789abcdef
print_string(lcd,"As RF Generator ")
-- delay
delay_1s(5)

var bit show = on

-- forever loop, fun is down here
forever loop
   -- I need to update the LCD & PLL?
   if (show == on) then
      -- Set the PLL to the new freq
      pll_set(freq)
      -- Show it on the LCD
      showit()
      -- flag down
      show = off
   end if
   --
   -- check for inputs
   -- UP first...
   tword = debounce(UP, updb)
   if (tword == 2) then
      -- +1 and update
      freq = freq + PLL_R
      show = on
   end if
   --
   -- DOWN ...
   tword = debounce(DOWN, dwdb)
   if (tword == 2) then
      -- -1 and update
      freq = freq - PLL_R
      show = on
   end if
end loop

Generated by JALlib CHM Help System | Source: format.jal


format_dword_hex - JALlib Procedures Help

format_dword_hex JALLIB PROCEDURE

Signature

procedure format_dword_hex(volatile byte out device, dword in data) is

Description

writes hex formatted dword to output device

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - dword in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_sbyte_dec - JALlib Procedures Help

format_sbyte_dec JALLIB PROCEDURE

Signature

procedure format_sbyte_dec(volatile byte out device, sbyte in data, byte in n_tot, byte in n2) is

Description

writes decimal formatted signed byte to output device
the output can be specified as a fraction
n_tot = the total length (including sign and decimal point)
n2 = number of digits behind the point

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - sbyte in
  • n_tot - byte in
  • n2 - byte in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_sdword_dec - JALlib Procedures Help

format_sdword_dec JALLIB PROCEDURE

Signature

procedure format_sdword_dec(volatile byte out device, sdword in data, byte in n_tot, byte in n2) is

Description

writes decimal formatted signed dword to output device
the output can be specified as a fraction
n_tot = the total length (including sign and decimal point)
n2 = number of digits behind the point

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - sdword in
  • n_tot - byte in
  • n2 - byte in

Return Value

None

Example

From sample file: 18f67j50_temperature_tc77.jal

-- Title: Test file for TC77 temperature sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads temperature from TC77 through SPI.
--
-- Sources:
-- TC77 temperature sensor sample by Eur van Andel
-- http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010750
--
-- Notes:
-- This is a complete re-write of the orignal jallib TC77 library
-- written by Eur van Andel.
--
-- Improvements:
-- Uses pesudo variables
-- tiny bit less code/ram usage.
-- cs line controlled by library (optional)
-- no ASM
-- Compatible with the jallib SPI library (hardware or software)
-- Less code used when using multiple devices since SPI code is shared.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_temperature_tc77.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize
;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include print

include format

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- Setup TC77 temp sensor
alias tc77_cs           is pin_ss
alias tc77_cs_direction is pin_ss_direction
tc77_cs = high
tc77_cs_direction = output
--
const TC77_CS_IN_LIB = TRUE  -- chip select line controlled by library
alias tc77_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 0,0
include temperature_tc77

-- main program
forever loop
   print_crlf(serial_hw_data)
   print_sbyte_dec(serial_data, tc77_celsius_sbyte)
   serial_data =" "

   print_crlf(serial_hw_data)
   format_sword_dec(serial_data, tc77_celsius_sword, 6, 2)
   serial_data =" "

   print_crlf(serial_hw_data)
   format_sdword_dec(serial_data, tc77_celsius_sdword, 8, 4)
   serial_data = " "

   _usec_delay(250_000)
end loop

Generated by JALlib CHM Help System | Source: format.jal


format_sword_dec - JALlib Procedures Help

format_sword_dec JALLIB PROCEDURE

Signature

procedure format_sword_dec(volatile byte out device, sword in data, byte in n_tot, byte in n2) is

Description

writes decimal formatted signed word to output device
the output can be specified as a fraction
n_tot = the total length (including sign and decimal point)
n2 = number of digits behind the point

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - sword in
  • n_tot - byte in
  • n2 - byte in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_time_hm - JALlib Procedures Help

format_time_hm JALLIB PROCEDURE

Signature

procedure format_time_hm(volatile byte out device,byte in HH, byte in MM) is

Description

Displays a time in HH:MM notation at specified position
Hours and minutes are specified separate

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • HH - byte in
  • MM - byte in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_time_hm_word - JALlib Procedures Help

format_time_hm_word JALLIB PROCEDURE

Signature

procedure format_time_hm_word(volatile byte out device,word in minutes) is

Description

Displays a time in HH:MM notation at specified position
the input is specified in minutes

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • minutes - word in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_time_hms - JALlib Procedures Help

format_time_hms JALLIB PROCEDURE

Signature

procedure format_time_hms(volatile byte out device,byte in HH, byte in MM, byte in SS) is

Description

Displays a time in HH:MM:SS notation at specified position
Hours and minutes are specified separate

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • HH - byte in
  • MM - byte in
  • SS - byte in

Return Value

None

Example

From sample file: 16f877a_ds1307_sw.jal

-- ------------------------------------------------------
-- Title:  DS1307 - Real Time Clock
--
-- Author: Enzo SERAFINI, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This sample show an example to setup hours, minutes and seconds and display on LCD
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:  Jean-Bernard - DS1307 lib.
--
-- Notes:
--  - File creation date/time: 13 Jun 2011.
--
-- ------------------------------------------------------

include 16f877a                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      HS               -- HS crystal or resonator
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      enabled      -- allow Low Voltage Programming
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

-- lcd config
const byte LCD_ROWS    =  4           -- LCD with 4 lines
const byte LCD_CHARS   =  20          -- and 20 characters per line
--
alias     lcd_en       is pin_D4      -- data trigger
alias     lcd_rs       is pin_D5      -- command/data select.
pin_D4_direction       = output
pin_D5_direction       = output
--
alias     lcd_d4       is pin_D0
alias     lcd_d5       is pin_D1
alias     lcd_d6       is pin_D2
alias     lcd_d7       is pin_D3
--
pin_D0_direction       = output
pin_D1_direction       = output
pin_D2_direction       = output
pin_D3_direction       = output
--
include lcd_hd44780_4
--
lcd_init()                            -- init the lcd controller

-- i2c config
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software    -- include i2c software lib

i2c_initialize()

include delay           -- include delay lib
include print           -- include print lib
include format          -- include format lib

include rtc_ds1307          -- include ds1307 rtc lib

ds1307_init()

-- define strings

var byte str1[] = "Set Time"
var byte str2[] = "hours"
var byte str3[] = "minutes"
var byte str4[] = "seconds"
var byte str5[] = "RTC :"

-- define variables

var byte h , m , s

-- define pins

alias     sw1       is pin_A0
alias     sw2       is pin_A1
alias     sw3       is pin_A2
--
pin_A0_direction       = input
pin_A1_direction       = input
pin_A2_direction       = input

-- Setup hours, minutes and seconds

lcd_cursor_position( 0,0 )
print_string(lcd,str1)                        -- Display "Set Time"
delay_100ms(10)
h = 0
while sw1 != high loop                        -- Setup hours

   if sw2 == high then h = h + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then h = h - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if h == 24 then h = 0 end if
   if h == 255 then h = 23 end if
   lcd_cursor_position( 1,0 )
   print_string(lcd,str2)                    -- Display "hours"
   lcd_cursor_position( 1,9 )
   format_byte_dec(lcd,h,2,0)               -- Display set hours
end loop
delay_100ms(10)
m = 0
while sw1 != high loop                        -- Setup minutes
   if sw2 == high then m = m + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then m = m - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if m == 60 then m = 0 end if
   if m == 255 then m = 59 end if
   lcd_cursor_position( 2,0 )
   print_string(lcd,str3)                    -- Display "minutes"
   lcd_cursor_position( 2,9 )
   format_byte_dec(lcd,m,2,0)               -- Display set minutes
end loop
delay_100ms(10)
s = 0
while sw1 != high loop                        -- Setup seconds
   if sw2 == high then s = s + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then s = s - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if s == 60 then s = 0 end if
   if s == 255 then s = 59 end if
   lcd_cursor_position( 3,0 )
   print_string(lcd,str4)                    -- Display "seconds"
   lcd_cursor_position( 3,9)
   format_byte_dec(lcd,s,2,0)               -- Dsiplay set seconds
end loop

-- write hours, minutes and seconds in the DS1307

ds1307_write( 0x00 , s )      -- seconds
ds1307_write( 0x01 , m )      -- minutes
ds1307_write( 0x02 , h )      -- hours

lcd_clear_line(0)

forever loop

   ds1307_read( 0x00 , s )      -- seconds
   ds1307_read( 0x01 , m )      -- minutes
   ds1307_read( 0x02 , h )      -- hours

   lcd_cursor_position( 0,0 )
   print_string(lcd,str5)        -- Display "RTC :"
   lcd_cursor_position( 0,7 )
   format_time_hms(lcd,h, m,s)   -- Display hh:mm:ss

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_word_dec - JALlib Procedures Help

format_word_dec JALLIB PROCEDURE

Signature

procedure format_word_dec(volatile byte out device, word in data, byte in n_tot, byte in n2) is

Description

writes decimal formatted word to output device
the output can be specified as a fraction
n_tot = the total length (including sign and decimal point)
n2 = number of digits behind the point

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - word in
  • n_tot - byte in
  • n2 - byte in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


format_word_hex - JALlib Procedures Help

format_word_hex JALLIB PROCEDURE

Signature

procedure format_word_hex(volatile byte out device, word in data) is

Description

writes hex formatted word to output device

Include

To use this procedure, include the library:

include format

Parameters

  • device - byte out
  • data - word in

Return Value

None

Example

From sample file: 16f648a_serial_format.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for format.jal
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_serial_format.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
const usart_hw_serial = true	-- true = RS232, false = SPI;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format

procedure plingcrlf() is
   serial_hw_data = "!"
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

procedure line(byte in nr) is
   serial_hw_data = nr + "0"
   serial_hw_data = " "

   for 20 loop
      serial_hw_data = "-"
   end loop
   serial_hw_data = 13
   serial_hw_data = 10
end procedure

forever loop                                  -- loop forever

   serial_hw_data = "T"    serial_hw_data = "e"    serial_hw_data = "s"    serial_hw_data = "t"    serial_hw_data = ":"    serial_hw_data = " "
   plingcrlf()
   line(0) -- --------------------------------------------------------------------

   -- hex byte output
   format_byte_hex(serial_hw_data, 0xEA)
   plingcrlf()

   -- hex word output
   format_word_hex(serial_hw_data, 0xFD22) -- VIC20 reset vector ;-)
   plingcrlf()

   -- hex word output
   format_dword_hex(serial_hw_data, 0x12345678)
   plingcrlf()
   line(1) -- --------------------------------------------------------------------

   -- decimal output ' 1.2'
   format_byte_dec(serial_hw_data, 12, 3, 1)
   plingcrlf()

   -- decimal output '0.12'
   format_byte_dec(serial_hw_data, 12, 3, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_byte_dec(serial_hw_data, 12, 3, 0)
   plingcrlf()

   -- decimal output '12.0'
   format_byte_dec(serial_hw_data, 120, 3, 1)
   plingcrlf()
   line(2) -- --------------------------------------------------------------------

   -- decimal output '-12'
   format_sbyte_dec(serial_hw_data, -12, 4, 0)
   plingcrlf()

   -- decimal output '-1.2'
   format_sbyte_dec(serial_hw_data, -12, 4, 1)
   plingcrlf()

   -- decimal output '-0.12'
   format_sbyte_dec(serial_hw_data, -12, 4, 2)
   plingcrlf()

   -- decimal output ' 12'
   format_sbyte_dec(serial_hw_data,  12, 4, 0)
   plingcrlf()

   -- decimal output ' 1.2'
   format_sbyte_dec(serial_hw_data,  12, 4, 1)
   plingcrlf()

   -- decimal output ' 0.12'
   format_sbyte_dec(serial_hw_data,  12, 4, 2)
   plingcrlf()

   line(3) -- --------------------------------------------------------------------

   -- decimal output ' 0.012'
   format_word_dec(serial_hw_data, 12, 6, 3)
   plingcrlf()

   -- decimal output '   1.2'
   format_word_dec(serial_hw_data, 12, 6, 1)
   plingcrlf()

   -- decimal output '   12'
   format_word_dec(serial_hw_data, 12, 6, 0)
   plingcrlf()

   -- decimal output ' -0.012'
   format_sword_dec(serial_hw_data, -12, 6, 3)
   plingcrlf()

   -- decimal output '23:55'
   format_time_hm(serial_hw_data, 23, 55)  -- 5 minutes to midnight
   plingcrlf()

   -- decimal output '23:56'
   format_time_hm_word(serial_hw_data, 23 * 60 + 56)  -- 4 minutes to midnight
   plingcrlf()

   serial_hw_data = "E"    serial_hw_data = "n"    serial_hw_data = "d"
   plingcrlf()
   plingcrlf()

   delay_100ms(30)

end loop

Generated by JALlib CHM Help System | Source: format.jal


g370_calbr - JALlib Procedures Help

g370_calbr JALLIB FUNCTION

Signature

function g370_calbr(word in an) return word is

Description

This function assumes 20.95% oxygen concentration and returns
the calibrating value. Call this one when your sensor breathes well ventilated air.
Store the calibration value for use with the g370_ox() function.

Include

To use this procedure, include the library:

include goel370

Parameters

  • an - word in

Return Value

word - Function return value

Example

From sample file: 18f2585_oxygen_goel370.jal

-- ------------------------------------------------------
-- Title: Measure oxygen concentration with the GOEL370 and a pic18f2585
--
-- Author: Eur van Andel, eir@fiwihex.nl, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by: Rob Hamerling
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Measure oxygen concentration via amplified signal of GOEL370 oxygen sensor,
-- made by Greisinger.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources: http://www.greisinger.de/   manufacturer of sensor
--
-- Notes:
-- see goel370.jal in ~/jallib/include/external/oxygen
--
-- ------------------------------------------------------

include 18f2585
pragma target clock 20_000_000
-- pragma target OSC  HS_PLL
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off              -- no watchdog

enable_digital_io()

pin_a0_direction = input        -- analog inputs to oxygen sensors
pin_a1_direction = input

ADCON0_ADON = true          -- AD converter enabled
ADCON1_VCFG = 0b00          -- Vref+ and Vref- are default Vdd and Vss
ADCON1_PCFG = 0b1101        -- AN0, AN1 analog input
ADCON2_ADFM = 1             -- right justified
ADCON2_ADCS = 0b101         -- Fosc/16

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_a4    -- red and green LEDs on Sterm daughterboard
var bit led_dir  is pin_a4_direction

led_dir = output
led = high

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_a5
var bit lcd_sterm_pin_dir is pin_a5_direction
include lcd_sterm_master         -- Sterm LCD + keyboard over single pin, contains a PIC too
const print_string_terminator = 255     -- fixes bug in print_string()
include print
include format

-- this example has two oxygen sensors, on AN1 and AN2
-- both are amplified 100 times, so 0..40mV sensor voltage = 0..4V analog voltage

var word an_ox[2]                -- 0..818 analog oxygen value
var word oxygen[2]               -- 0..100% Oxygen, calibrated at 21% = 2100
var word calibr[2]               -- calibration value
calibr[0] = 900                  -- close to calibration value at 100x amplification
calibr[1] = 900

include goel370                  -- sensor library

var bit toggle                   -- to see LED flicker

-- start of procedure block --------------------------------------------------

procedure leds(byte in x) is  -- four leds, all connected in series between +5V and GND
if x == down then             -- at 1.7V Vf, they will not light up
   led_dir  = input           -- PIC pin is tied to the middle, via 150 Ohm resistor
elsif x == red then           -- so HIGH will light both lower green LEDs
   led_dir  = output          -- LOW will light both higher RED leds
   led      = low             -- pin_direction = input will light no LEDs.
elsif x == green then
   led_dir  = output
    led     = high
end if
end procedure

-- there is a proper analog library, but I'm too old to learn that
function get_analog(byte in channel) return word is
    var word analog
    if channel > 4 then -- PIC18F2585 with 28 pins only has 5 analog channels
       channel = 4
    end if

    ADCON0_CHS = channel
    delay_1ms(1)               -- we have all the time in the world
    ADCON0_GO = true
    while ADCON0_NDONE loop end loop    -- wait for AD conversion to complete
    return ADRES
end function

-- -------------- end procedure block -------------------------------------

-- --------------------------------------  S T A R T  M A I N  --------------------

-- wait for STERM Slave to power-up and initialize.

lcd_clear_screen()

for 4 loop                 -- red/green sequence means boot
   leds(red)
   delay_100ms(2)
   lcd_clear_screen()      -- Sterm needs some time after power-up
   leds(green)
   delay_100ms(2)
end loop

--                 12345678901234567890
const byte str8[]="Oxygen%  C=calibrate"  -- print banner
const byte str9[] ="an"
const byte str10[]="Oxygen"
const byte str11[]="    CALIBRATION     "
const byte str12[]="Cbr"

lcd_cursor_position(0,0)      -- first line: banner
print_string(lcd, str8)

forever loop -- ---------------------------  M A I N  L O O P  ----------------------------

   lcd_cursor_position(1,0)      -- second line: values
   var byte i
   for 2 using i loop
      an_ox[i] = get_analog(i)
      oxygen[i] = g370_ox(an_ox[i], calibr[i])  -- value is 100x actual concentration

      print_string(lcd, str9)
      lcd = i + 48   -- ASCII 0
      lcd = "="
      print_word_dec(lcd, an_ox[i])
      lcd = " "
   end loop

   lcd_cursor_position(2,0)      -- second line: first value
   print_string(lcd, str10)
   lcd = "0"
   lcd = "="
   format_word_dec(lcd, oxygen[0], 5, 2)  -- two digits after decimal point
   lcd = "%"

   lcd_cursor_position(3,0)      -- third line: second value
   print_string(lcd, str10)
   lcd = "1"
   lcd = "="
   format_word_dec(lcd, oxygen[1], 5, 2)
   lcd = "%"
   delay_100ms(2)

   if getkey() == 0x0C then
      lcd_clear_screen()
      lcd_cursor_position(1,0)      -- second line: banner
      print_string(lcd, str11)
      an_ox[0] = get_analog(0)
      calibr[0] = g370_calbr(an_ox[0])
      an_ox[1] = get_analog(1)
      calibr[1] = g370_calbr(an_ox[1])
      lcd_cursor_position(2,0)      -- third line: calibration values
      print_string(lcd, str12)
      lcd = "0"
      lcd = "="
      print_word_dec(lcd, calibr[0])
      lcd = " "
      print_string(lcd, str12)
      lcd = "0"
      lcd = "="
      print_word_dec(lcd, calibr[1])
      lcd = " "
      delay_1s(3)             -- keep values visible for operator
      lcd_clear_screen()
      lcd_cursor_position(0,0)      -- first line: banner
      print_string(lcd, str8)
   end if

   toggle = ! toggle

   if toggle then
      leds(green)
   else
      leds(down)
   end if

end loop          -- waiting for "B" to be pressed

Generated by JALlib CHM Help System | Source: goel370.jal


g370_ox - JALlib Procedures Help

g370_ox JALLIB FUNCTION

Signature

function g370_ox(word in an, word in calibr) return word is

Description

This function takes the word output of the D/A converter (0..1023) and the calibration value
it returns a word value of the oxygen concentration in % * 100. So if the oxygen concentration is
21%, the function returns 2100.

Include

To use this procedure, include the library:

include goel370

Parameters

  • an - word in
  • calibr - word in

Return Value

word - Function return value

Example

From sample file: 18f2585_oxygen_goel370.jal

-- ------------------------------------------------------
-- Title: Measure oxygen concentration with the GOEL370 and a pic18f2585
--
-- Author: Eur van Andel, eir@fiwihex.nl, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by: Rob Hamerling
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Measure oxygen concentration via amplified signal of GOEL370 oxygen sensor,
-- made by Greisinger.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources: http://www.greisinger.de/   manufacturer of sensor
--
-- Notes:
-- see goel370.jal in ~/jallib/include/external/oxygen
--
-- ------------------------------------------------------

include 18f2585
pragma target clock 20_000_000
-- pragma target OSC  HS_PLL
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off              -- no watchdog

enable_digital_io()

pin_a0_direction = input        -- analog inputs to oxygen sensors
pin_a1_direction = input

ADCON0_ADON = true          -- AD converter enabled
ADCON1_VCFG = 0b00          -- Vref+ and Vref- are default Vdd and Vss
ADCON1_PCFG = 0b1101        -- AN0, AN1 analog input
ADCON2_ADFM = 1             -- right justified
ADCON2_ADCS = 0b101         -- Fosc/16

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_a4    -- red and green LEDs on Sterm daughterboard
var bit led_dir  is pin_a4_direction

led_dir = output
led = high

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_a5
var bit lcd_sterm_pin_dir is pin_a5_direction
include lcd_sterm_master         -- Sterm LCD + keyboard over single pin, contains a PIC too
const print_string_terminator = 255     -- fixes bug in print_string()
include print
include format

-- this example has two oxygen sensors, on AN1 and AN2
-- both are amplified 100 times, so 0..40mV sensor voltage = 0..4V analog voltage

var word an_ox[2]                -- 0..818 analog oxygen value
var word oxygen[2]               -- 0..100% Oxygen, calibrated at 21% = 2100
var word calibr[2]               -- calibration value
calibr[0] = 900                  -- close to calibration value at 100x amplification
calibr[1] = 900

include goel370                  -- sensor library

var bit toggle                   -- to see LED flicker

-- start of procedure block --------------------------------------------------

procedure leds(byte in x) is  -- four leds, all connected in series between +5V and GND
if x == down then             -- at 1.7V Vf, they will not light up
   led_dir  = input           -- PIC pin is tied to the middle, via 150 Ohm resistor
elsif x == red then           -- so HIGH will light both lower green LEDs
   led_dir  = output          -- LOW will light both higher RED leds
   led      = low             -- pin_direction = input will light no LEDs.
elsif x == green then
   led_dir  = output
    led     = high
end if
end procedure

-- there is a proper analog library, but I'm too old to learn that
function get_analog(byte in channel) return word is
    var word analog
    if channel > 4 then -- PIC18F2585 with 28 pins only has 5 analog channels
       channel = 4
    end if

    ADCON0_CHS = channel
    delay_1ms(1)               -- we have all the time in the world
    ADCON0_GO = true
    while ADCON0_NDONE loop end loop    -- wait for AD conversion to complete
    return ADRES
end function

-- -------------- end procedure block -------------------------------------

-- --------------------------------------  S T A R T  M A I N  --------------------

-- wait for STERM Slave to power-up and initialize.

lcd_clear_screen()

for 4 loop                 -- red/green sequence means boot
   leds(red)
   delay_100ms(2)
   lcd_clear_screen()      -- Sterm needs some time after power-up
   leds(green)
   delay_100ms(2)
end loop

--                 12345678901234567890
const byte str8[]="Oxygen%  C=calibrate"  -- print banner
const byte str9[] ="an"
const byte str10[]="Oxygen"
const byte str11[]="    CALIBRATION     "
const byte str12[]="Cbr"

lcd_cursor_position(0,0)      -- first line: banner
print_string(lcd, str8)

forever loop -- ---------------------------  M A I N  L O O P  ----------------------------

   lcd_cursor_position(1,0)      -- second line: values
   var byte i
   for 2 using i loop
      an_ox[i] = get_analog(i)
      oxygen[i] = g370_ox(an_ox[i], calibr[i])  -- value is 100x actual concentration

      print_string(lcd, str9)
      lcd = i + 48   -- ASCII 0
      lcd = "="
      print_word_dec(lcd, an_ox[i])
      lcd = " "
   end loop

   lcd_cursor_position(2,0)      -- second line: first value
   print_string(lcd, str10)
   lcd = "0"
   lcd = "="
   format_word_dec(lcd, oxygen[0], 5, 2)  -- two digits after decimal point
   lcd = "%"

   lcd_cursor_position(3,0)      -- third line: second value
   print_string(lcd, str10)
   lcd = "1"
   lcd = "="
   format_word_dec(lcd, oxygen[1], 5, 2)
   lcd = "%"
   delay_100ms(2)

   if getkey() == 0x0C then
      lcd_clear_screen()
      lcd_cursor_position(1,0)      -- second line: banner
      print_string(lcd, str11)
      an_ox[0] = get_analog(0)
      calibr[0] = g370_calbr(an_ox[0])
      an_ox[1] = get_analog(1)
      calibr[1] = g370_calbr(an_ox[1])
      lcd_cursor_position(2,0)      -- third line: calibration values
      print_string(lcd, str12)
      lcd = "0"
      lcd = "="
      print_word_dec(lcd, calibr[0])
      lcd = " "
      print_string(lcd, str12)
      lcd = "0"
      lcd = "="
      print_word_dec(lcd, calibr[1])
      lcd = " "
      delay_1s(3)             -- keep values visible for operator
      lcd_clear_screen()
      lcd_cursor_position(0,0)      -- first line: banner
      print_string(lcd, str8)
   end if

   toggle = ! toggle

   if toggle then
      leds(green)
   else
      leds(down)
   end if

end loop          -- waiting for "B" to be pressed

Generated by JALlib CHM Help System | Source: goel370.jal


get_co2_ppm - JALlib Procedures Help

get_co2_ppm JALLIB FUNCTION

Signature

function get_co2_ppm() return word is

Description

returns a word with CO2 concentration in ppm
note: if sensor is busy measuring the CO2 values, it will give garbage reply
reply is checked for garbage and if so, *PREVIOUS* ppm value is returned

Include

To use this procedure, include the library:

include co2_t6603

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f876a_co2_t6603.jal

-- Title: read CO2 values from GE/Telaire T6603 CO2 sensor, show on LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read CO2 concentration values
-- from the GE/Telaire CO2 sensor, using the serial_hardware, delay
-- and t6603_co2 library. It uses a 4x20 LCD for user interaction.
-- The T6603 uses 3.3V serial signals, negative logic at 19k2 baud.
-- Use a level converter like the 74xx07 with both 5V and 3.3V pullups.
--
-- This file has been generated by hand (manually maintained)
--
-- Note: the CO2 sensor needs some 20s to get heated after powerup. Just wait.
-- The sensor sometimes gives a wrong value, this is just after it
-- updates the internal value. This can be overcome by polling the status byte
-- until it is non-zero, then waiting for a second before polling the ppm value.
-- This is not done here.

const version_h = 0
const version_l = 4

-- select PIC
include 16f876a

pragma target clock     20_000_000     -- 20 MHz xtal
pragma target OSC    HS
pragma target WDT    disabled    -- no watchdog, please
pragma target LVP    enabled     -- allow low voltage programming, frees up pin_b3

-- set all IO as digital
enable_digital_io()

-- ------------------- INCLUDE LIBRARIES --------------------------

const usart_hw_serial      = true   -- true = RS232, false = SPI
const serial_hw_baudrate   = 19_200
include serial_hardware
serial_hw_init()           -- calculate baudrate, turn peripheral on

const byte LCD_CHARS = 20
const byte  LCD_ROWS = 4

alias LCD_RS           is pin_b5       -- LCD command/data select.
alias LCD_EN           is pin_b4       -- LCD data trigger
alias LCD_dataport     is portb_low    -- LCD data nibble
portb_direction        = all_output    -- LCD data is portb_low
include lcd_hd44780_4                  -- LCD library with 4 data lines
lcd_init()

include print                          -- nice formatted output

delay_100ms(5)                      -- to get the LCD up & running

include co2_t6603                      -- actual CO2 library

-- ---------------- VARIABLES ---------------------------

var word co2                  -- in ppm

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
lcd_cursor_position(0,0)
const byte str1[] = "sample T6603 CO2"
print_string(lcd, str1)               -- output string to LCD
lcd_cursor_position(1,0)              -- second line of display

forever loop

   CO2 = get_co2_ppm()
   lcd_cursor_position(1, 0)             -- row 2,
   print_word_dec(lcd, CO2)
   lcd="p" lcd="p" lcd="m" lcd =" " lcd =" " lcd =" "

   delay_100ms(10)                  -- don't poll sensor too often

end loop

Generated by JALlib CHM Help System | Source: co2_t6603.jal


getkey - JALlib Procedures Help

getkey JALLIB FUNCTION

Signature

function getkey() return byte is

Description

getkey - return the key pressed (until it is released)

Include

To use this procedure, include the library:

include lcd_sterm_master

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f2585_oxygen_goel370.jal

-- ------------------------------------------------------
-- Title: Measure oxygen concentration with the GOEL370 and a pic18f2585
--
-- Author: Eur van Andel, eir@fiwihex.nl, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by: Rob Hamerling
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Measure oxygen concentration via amplified signal of GOEL370 oxygen sensor,
-- made by Greisinger.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources: http://www.greisinger.de/   manufacturer of sensor
--
-- Notes:
-- see goel370.jal in ~/jallib/include/external/oxygen
--
-- ------------------------------------------------------

include 18f2585
pragma target clock 20_000_000
-- pragma target OSC  HS_PLL
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off              -- no watchdog

enable_digital_io()

pin_a0_direction = input        -- analog inputs to oxygen sensors
pin_a1_direction = input

ADCON0_ADON = true          -- AD converter enabled
ADCON1_VCFG = 0b00          -- Vref+ and Vref- are default Vdd and Vss
ADCON1_PCFG = 0b1101        -- AN0, AN1 analog input
ADCON2_ADFM = 1             -- right justified
ADCON2_ADCS = 0b101         -- Fosc/16

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_a4    -- red and green LEDs on Sterm daughterboard
var bit led_dir  is pin_a4_direction

led_dir = output
led = high

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_a5
var bit lcd_sterm_pin_dir is pin_a5_direction
include lcd_sterm_master         -- Sterm LCD + keyboard over single pin, contains a PIC too
const print_string_terminator = 255     -- fixes bug in print_string()
include print
include format

-- this example has two oxygen sensors, on AN1 and AN2
-- both are amplified 100 times, so 0..40mV sensor voltage = 0..4V analog voltage

var word an_ox[2]                -- 0..818 analog oxygen value
var word oxygen[2]               -- 0..100% Oxygen, calibrated at 21% = 2100
var word calibr[2]               -- calibration value
calibr[0] = 900                  -- close to calibration value at 100x amplification
calibr[1] = 900

include goel370                  -- sensor library

var bit toggle                   -- to see LED flicker

-- start of procedure block --------------------------------------------------

procedure leds(byte in x) is  -- four leds, all connected in series between +5V and GND
if x == down then             -- at 1.7V Vf, they will not light up
   led_dir  = input           -- PIC pin is tied to the middle, via 150 Ohm resistor
elsif x == red then           -- so HIGH will light both lower green LEDs
   led_dir  = output          -- LOW will light both higher RED leds
   led      = low             -- pin_direction = input will light no LEDs.
elsif x == green then
   led_dir  = output
    led     = high
end if
end procedure

-- there is a proper analog library, but I'm too old to learn that
function get_analog(byte in channel) return word is
    var word analog
    if channel > 4 then -- PIC18F2585 with 28 pins only has 5 analog channels
       channel = 4
    end if

    ADCON0_CHS = channel
    delay_1ms(1)               -- we have all the time in the world
    ADCON0_GO = true
    while ADCON0_NDONE loop end loop    -- wait for AD conversion to complete
    return ADRES
end function

-- -------------- end procedure block -------------------------------------

-- --------------------------------------  S T A R T  M A I N  --------------------

-- wait for STERM Slave to power-up and initialize.

lcd_clear_screen()

for 4 loop                 -- red/green sequence means boot
   leds(red)
   delay_100ms(2)
   lcd_clear_screen()      -- Sterm needs some time after power-up
   leds(green)
   delay_100ms(2)
end loop

--                 12345678901234567890
const byte str8[]="Oxygen%  C=calibrate"  -- print banner
const byte str9[] ="an"
const byte str10[]="Oxygen"
const byte str11[]="    CALIBRATION     "
const byte str12[]="Cbr"

lcd_cursor_position(0,0)      -- first line: banner
print_string(lcd, str8)

forever loop -- ---------------------------  M A I N  L O O P  ----------------------------

   lcd_cursor_position(1,0)      -- second line: values
   var byte i
   for 2 using i loop
      an_ox[i] = get_analog(i)
      oxygen[i] = g370_ox(an_ox[i], calibr[i])  -- value is 100x actual concentration

      print_string(lcd, str9)
      lcd = i + 48   -- ASCII 0
      lcd = "="
      print_word_dec(lcd, an_ox[i])
      lcd = " "
   end loop

   lcd_cursor_position(2,0)      -- second line: first value
   print_string(lcd, str10)
   lcd = "0"
   lcd = "="
   format_word_dec(lcd, oxygen[0], 5, 2)  -- two digits after decimal point
   lcd = "%"

   lcd_cursor_position(3,0)      -- third line: second value
   print_string(lcd, str10)
   lcd = "1"
   lcd = "="
   format_word_dec(lcd, oxygen[1], 5, 2)
   lcd = "%"
   delay_100ms(2)

   if getkey() == 0x0C then
      lcd_clear_screen()
      lcd_cursor_position(1,0)      -- second line: banner
      print_string(lcd, str11)
      an_ox[0] = get_analog(0)
      calibr[0] = g370_calbr(an_ox[0])
      an_ox[1] = get_analog(1)
      calibr[1] = g370_calbr(an_ox[1])
      lcd_cursor_position(2,0)      -- third line: calibration values
      print_string(lcd, str12)
      lcd = "0"
      lcd = "="
      print_word_dec(lcd, calibr[0])
      lcd = " "
      print_string(lcd, str12)
      lcd = "0"
      lcd = "="
      print_word_dec(lcd, calibr[1])
      lcd = " "
      delay_1s(3)             -- keep values visible for operator
      lcd_clear_screen()
      lcd_cursor_position(0,0)      -- first line: banner
      print_string(lcd, str8)
   end if

   toggle = ! toggle

   if toggle then
      leds(green)
   else
      leds(down)
   end if

end loop          -- waiting for "B" to be pressed

Generated by JALlib CHM Help System | Source: lcd_sterm_master.jal


getkey_once - JALlib Procedures Help

getkey_once JALLIB FUNCTION

Signature

function getkey_once() return byte is

Description

getkey_once - return the value of a key pressed only once

Include

To use this procedure, include the library:

include lcd_sterm_master

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f88_keyboard.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for keyboard
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing keyboard (4x4, 3x4)
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
-- setup:   A keyboard 4x3 or 4x4 connected to two half ports
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f88_js.jal
--    * test : test_keyboard.jal
--

;@jallib section chipdef
-- chip setup
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       enabled        -- allow low-voltage programming
pragma target CCP1MUX   pin_B3         -- ccp1 pin on B3

--
-- This setup uses the internal oscillator
;pragma target OSC       INTOSC_NOCLKOUT   -- internal oscillator
;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   pin_B3            -- ccp1 pin on B3
;OSCCON_IRCF = 7                           -- set prescaler to 1 (8 MHz)

include delay
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

-- keyboard - setup the two half ports
-- (rows and cols can be on separte ports - unlikely setup for dwarf-board)
alias keyscan  is porta_low      -- rows of keyboard
alias keydrive is portb_low      -- columns of keyboard
alias keydrive_direction is portb_low_direction

include keyboard  -- check this libraray for keyboad schematics

-- -------------------------- PROGRAM START----------------------------
const byte str1[] = " - Test keyboard.jal- bytes\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

var byte key

forever loop
   key = getkey()
   print_byte_dec(serial_hw_data,  key)

   serial_hw_data = " "

   key = getkey_once()
   print_byte_dec(serial_hw_data,  key)

   print_crlf(serial_hw_data)
   delay_100ms(2)
end loop

Generated by JALlib CHM Help System | Source: lcd_sterm_master.jal


glcd_4x6_font.jal - JALLIB Library Documentation

glcd_4x6_font.jal JALLIB LIBRARY

Title

4X6 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library 4X6 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_4X6 - const byte = 0x01
FONT_4X6_WIDTH - const byte = 4
FONT_4X6_HEIGHT - const byte = 6
FONT_4X6_BYTE_PER_CHAR - const byte = 6
FONT_4X6_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_5x7_font.jal - JALLIB Library Documentation

glcd_5x7_font.jal JALLIB LIBRARY

Title

5X7 font lookup table for GLCD with pcd8544 controller used in Nokia 3310

Author

Andre Miller Copyright (c) 2008..2022, all rights reserved., Adapted-by: Richard Zengerink, Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 5X7 font lookup table for Nokia 3310 display with pcd8544 controller

Notes

See lib glcd_font.jal for font explanation

font ID, unique amongst font libs

Sources

http://www.amontec.com/lcd_nokia_3310.shtml

Constants and Variables

FONT_5X7 - const byte = 0x02
FONT_5X7_BYTE_PER_CHAR - const byte = 5
FONT_5X7_WIDTH - const byte = 5
FONT_5X7_HEIGHT - const byte = 7
FONT_5X7_BIT_DIRECTION - const byte = FONT_BOTTOM_LEFT_VERTICAL


glcd_5x8_font.jal - JALLIB Library Documentation

glcd_5x8_font.jal JALLIB LIBRARY

Title

5X8 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 5X8 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_5X8 - const byte = 0x03
FONT_5X8_WIDTH - const byte = 5
FONT_5X8_HEIGHT - const byte = 8
FONT_5X8_BYTE_PER_CHAR - const byte = 8
FONT_5X8_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_5x12_font.jal - JALLIB Library Documentation

glcd_5x12_font.jal JALLIB LIBRARY

Title

5X12 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library 5X12 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_5X12 - const byte = 0x04
FONT_5X12_WIDTH - const byte = 5
FONT_5X12_HEIGHT - const byte = 12
FONT_5X12_BYTE_PER_CHAR - const byte = 12
FONT_5X12_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_6x8_font.jal - JALLIB Library Documentation

glcd_6x8_font.jal JALLIB LIBRARY

Title

6X8 font lookup table for GLCD with pcd8544 controller used in Nokia 3310

Author

Richard Zengerink Copyright (c) 2008..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 6X8 font lookup table for Nokia 3310 display with pcd8544 controller

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

http://www.amontec.com/lcd_nokia_3310.shtml

Constants and Variables

FONT_6X8 - const byte = 0x05
FONT_6X8_BYTE_PER_CHAR - const byte = 6
FONT_6X8_WIDTH - const byte = 6
FONT_6X8_HEIGHT - const byte = 8
FONT_6X8_BIT_DIRECTION - const byte = FONT_BOTTOM_LEFT_VERTICAL


glcd_6x8_u_font.jal - JALLIB Library Documentation

glcd_6x8_u_font.jal JALLIB LIBRARY

Title

6X8 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 6X8 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_6X8_U - const byte = 0x06
FONT_6X8_U_WIDTH - const byte = 6
FONT_6X8_U_HEIGHT - const byte = 8
FONT_6X8_U_BYTE_PER_CHAR - const byte = 8
FONT_6X8_U_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_6x10_font.jal - JALLIB Library Documentation

glcd_6x10_font.jal JALLIB LIBRARY

Title

6X10 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 6X10 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_6X10 - const byte = 0x07
FONT_6X10_WIDTH - const byte = 6
FONT_6X10_HEIGHT - const byte = 10
FONT_6X10_BYTE_PER_CHAR - const byte = 10
FONT_6X10_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_7x12_font.jal - JALLIB Library Documentation

glcd_7x12_font.jal JALLIB LIBRARY

Title

7X12 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 7X12 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_7X12 - const byte = 0x08
FONT_7X12_WIDTH - const byte = 7
FONT_7X12_HEIGHT - const byte = 12
FONT_7X12_BYTE_PER_CHAR - const byte = 12
FONT_7X12_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_7x12_u_font.jal - JALLIB Library Documentation

glcd_7x12_u_font.jal JALLIB LIBRARY

Title

7X12 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 7X12 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_7X12_U - const byte = 0x09
FONT_7X12_U_WIDTH - const byte = 7
FONT_7X12_U_HEIGHT - const byte = 12
FONT_7X12_U_BYTE_PER_CHAR - const byte = 12
FONT_7X12_U_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_8x8_font.jal - JALLIB Library Documentation

glcd_8x8_font.jal JALLIB LIBRARY

Title

8X8 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 8X8 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_8X8 - const byte = 0x0A
FONT_8X8_WIDTH - const byte = 8
FONT_8X8_HEIGHT - const byte = 8
FONT_8X8_BYTE_PER_CHAR - const byte = 8
FONT_8X8_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_8x12_font.jal - JALLIB Library Documentation

glcd_8x12_font.jal JALLIB LIBRARY

Title

8X12 font tables

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This sample can contain any 8X12 size font tables.

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

http://www.divshare.com/download/11463401-4a9

Constants and Variables

FONT_8X12 - const byte = 0x0B
FONT_8X12_WIDTH - const byte = 8
FONT_8X12_HEIGHT - const byte = 12
FONT_8X12_BYTE_PER_CHAR - const byte = 12
FONT_8X12_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_8x12_u_font.jal - JALLIB Library Documentation

glcd_8x12_u_font.jal JALLIB LIBRARY

Title

8X12 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 8X12 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_8X12_U - const byte = 0x0C
FONT_8X12_U_WIDTH - const byte = 8
FONT_8X12_U_HEIGHT - const byte = 12
FONT_8X12_U_BYTE_PER_CHAR - const byte = 12
FONT_8X12_U_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_8x14_font.jal - JALLIB Library Documentation

glcd_8x14_font.jal JALLIB LIBRARY

Title

8X14 font lookup table for GLCD

Author

Urmas Joeleht Copyright (c) 2015..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library 8X14 font lookup table for GLCD

Notes

See lib glcd_font.jal for font explanation

Font ID, unique amongst font libs.

Sources

https://github.com/DerBer/ht1632clib/tree/master/font

Constants and Variables

FONT_8X14 - const byte = 0x0D
FONT_8X14_WIDTH - const byte = 8
FONT_8X14_HEIGHT - const byte = 14
FONT_8X14_BYTE_PER_CHAR - const byte = 14
FONT_8X14_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_9x16_font.jal - JALLIB Library Documentation

glcd_9x16_font.jal JALLIB LIBRARY

Title

9X16 font table

Author

Rob Jansen Copyright (c) 2022..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

9X16 font lookup table.

Notes

See lib glcd_font.jal for font explanation.

Font ID, unique amongst font libs.

Sources

Unknown.

Constants and Variables

FONT_9X16 - const byte = 0x0E
FONT_9X16_WIDTH - const byte = 9
FONT_9X16_HEIGHT - const byte = 16
FONT_9X16_BYTE_PER_CHAR - const byte = 32
FONT_9X16_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_12x16_font.jal - JALLIB Library Documentation

glcd_12x16_font.jal JALLIB LIBRARY

Title

12X16 font table

Author

Rob Jansen Copyright (c) 2022..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

12X16 font lookup table.

Notes

See lib glcd_font.jal for font explanation.

Font ID, unique amongst font libs.

Sources

Unknown.

Constants and Variables

FONT_12X16 - const byte = 0x0F
FONT_12X16_WIDTH - const byte = 12
FONT_12X16_HEIGHT - const byte = 16
FONT_12X16_BYTE_PER_CHAR - const byte = 32
FONT_12X16_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_14x30_font.jal - JALLIB Library Documentation

glcd_14x30_font.jal JALLIB LIBRARY

Title

14X30 font table

Author

Rob Jansen Copyright (c) 2022..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

14X30 font lookup table.

Notes

See lib glcd_font.jal for font explanation.

Font ID, unique amongst font libs.

Sources

Unknown.

Constants and Variables

FONT_14X30 - const byte = 0x10
FONT_14X30_WIDTH - const byte = 14
FONT_14X30_HEIGHT - const byte = 30
FONT_14X30_BYTE_PER_CHAR - const byte = 60
FONT_14X30_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_16x32_font.jal - JALLIB Library Documentation

glcd_16x32_font.jal JALLIB LIBRARY

Title

14X30 font table

Author

Rob Jansen Copyright (c) 2022..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

16X32 font lookup table.

Notes

See lib glcd_font.jal for font explanation.

Font ID, unique amongst font libs.

Sources

Unknown.

Constants and Variables

FONT_16X32 - const byte = 0x11
FONT_16X32_WIDTH - const byte = 16
FONT_16X32_HEIGHT - const byte = 32
FONT_16X32_BYTE_PER_CHAR - const byte = 64
FONT_16X32_BIT_DIRECTION - const byte = FONT_TOP_LEFT_HORIZONTAL


glcd_box - JALlib Procedures Help

glcd_box JALLIB PROCEDURE

Signature

procedure glcd_box(byte*GLCD_X_SIZE in x0, byte*GLCD_Y_SIZE in y0,

Description

Purpose: Draw a rectangular box
Arguments: - x- and y-coordinates in pixels of upper left corner of the box
- x- and y-coordinates in pixels of lower right corner of the box
Notes: Using current pixel color
Author: Paul D'haene

Include

To use this procedure, include the library:

include glcd_common

Parameters

None

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_box_fill - JALlib Procedures Help

glcd_box_fill JALLIB PROCEDURE

Signature

procedure glcd_box_fill(byte*GLCD_X_SIZE in x0, byte*GLCD_Y_SIZE in y0,

Description

Purpose: Draw a filled rectangular box
Arguments: - x- and y-coordinates in pixels of upper left corner of the box
- x- and y-coordinates in pixels of lower right corner of the box
Notes: Using current pixel color
Author: Paul D'haene

Include

To use this procedure, include the library:

include glcd_common

Parameters

None

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_cache_update - JALlib Procedures Help

glcd_cache_update JALLIB PROCEDURE

Signature

procedure glcd_cache_update() is

Description

Copy the changed area of the cache to the lcd.
Call this procedure after writing to cache.
When the glcd_cache_changed flag has not been set, lcd_cache_update simply
returns. Only the cache between the low & high watermark pointers is
updated

Include

To use this procedure, include the library:

include glcd_nokia_5110

Parameters

None

Return Value

None

Example

From sample file: 18f4550_glcd_nokia_5110_image.jal

-- Title: GLCD Nokia 3310/5110 image demo sample. Drawing images.
-- Author: Rob Jansen, Copyright (c) 2021..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD for the Nokia 5110 display.
--              It demonstrates  the drawing of images on the display including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 84 x 48 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--

include 18f4550
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL
pragma target WDT       control    -- watchdog
pragma target LVP       enabled    -- use low Voltage Programming
pragma target MCLR      external   -- reset externally
WDTCON_SWDTEN = off                -- no watchdog

enable_digital_io()

-- Pin assignment for the Nokia display.
alias nokia_sclk       is pin_b6    --  assign nokia clock
alias nokia_sda        is pin_b4    --  assign nokia serial data in
alias nokia_res        is pin_c0    --  assign nokia reset
alias nokia_dc         is pin_c2    --  assign nokia data/commant
-- The chip select for the Nokia can be connected to ground to save a pin. If
-- to be controlled by the library then it can be defined here but all the
-- library does is enable the chip select when nokia_init() is called. If
-- used then define the following:
--    alias nokia_cs         is pin_c1    --  assign nokia chip select
--    pin_c1_direction = output

pin_b6_direction = output
pin_b4_direction = output
pin_c2_direction = output
pin_c0_direction = output

-- include glcd_6x8_font
include glcd_nokia_5110
nokia_init()

include glcd_common
include delay
include print
include glcd_5x7_font
include glcd_font

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Filled oval 84 x 48
const byte oval[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0xC0, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xF8, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE,
    0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xC0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFE, 0xFC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x1F,
    0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
    0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,
    0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[], byte in x_size, byte in y_size) is
   glcd_clear_cache()
   nokia_clear_screen()
   glcd_draw_image(image,0,0,x_size,y_size)
   glcd_cache_update()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   glcd_clear_cache()
   nokia_clear_screen()
     for 3 loop
      glcd_draw_image(battery_00,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_25,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_50,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   glcd_clear_cache()
   nokia_clear_screen()
    for 4 loop
      glcd_draw_image(envelope,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(envelope,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
    end loop
end procedure

-- Default pen color.
glcd_pen_color = GLCD_BLACK
glcd_font_use(FONT_5X7)
print_string(glcd,"Image demo !")
delay_1s(2)

forever loop

   -- Draw the images, one default, one inverted.
   draw_an_image(jal_logo,84,48)
   draw_an_image(marilyn,84,48)
   draw_an_image(oval,84,48)
   -- Show the battery charging.
   draw_battery_charging()
   -- Show drawing 2 icons dranw independently.
   draw_two_icons()

   -- Now display the inverted/normal image.
    if (glcd_pen_color == GLCD_BLACK)
    then
       glcd_pen_color = GLCD_WHITE
    else
       glcd_pen_color = GLCD_BLACK
    end if

end loop

Generated by JALlib CHM Help System | Source: glcd_nokia_5110.jal


glcd_char_goto - JALlib Procedures Help

glcd_char_goto JALLIB PROCEDURE

Signature

procedure glcd_char_goto(byte in x, byte in y) is

Description

Purpose: Set location of next character to write
Arguments: x- and y-coordinates in pixels of next character to read or write

Include

To use this procedure, include the library:

include glcd_common

Parameters

  • x - byte in
  • y - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_circle - JALlib Procedures Help

glcd_circle JALLIB PROCEDURE

Signature

procedure glcd_circle(byte*GLCD_X_SIZE in cx, byte*GLCD_Y_SIZE in cy, byte in radius) is

Description

Purpose: Draw a circle
arguments: - x- and -y-coordinates of the center of the circle
- radius radius of the circle
Notes: Using current pixel color
The circle code may not give a round circle on the glcd.
Author: Paul D'haene

Include

To use this procedure, include the library:

include glcd_common

Parameters

  • cx - byte*GLCD_X_SIZE in
  • cy - byte*GLCD_Y_SIZE in
  • radius - byte in

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_clear_cache - JALlib Procedures Help

glcd_clear_cache JALLIB PROCEDURE

Signature

procedure glcd_clear_cache() is

Description

Clear the cache; glcd_cache_update() must be called next.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 18f4550_glcd_nokia_5110_image.jal

-- Title: GLCD Nokia 3310/5110 image demo sample. Drawing images.
-- Author: Rob Jansen, Copyright (c) 2021..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD for the Nokia 5110 display.
--              It demonstrates  the drawing of images on the display including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 84 x 48 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--

include 18f4550
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL
pragma target WDT       control    -- watchdog
pragma target LVP       enabled    -- use low Voltage Programming
pragma target MCLR      external   -- reset externally
WDTCON_SWDTEN = off                -- no watchdog

enable_digital_io()

-- Pin assignment for the Nokia display.
alias nokia_sclk       is pin_b6    --  assign nokia clock
alias nokia_sda        is pin_b4    --  assign nokia serial data in
alias nokia_res        is pin_c0    --  assign nokia reset
alias nokia_dc         is pin_c2    --  assign nokia data/commant
-- The chip select for the Nokia can be connected to ground to save a pin. If
-- to be controlled by the library then it can be defined here but all the
-- library does is enable the chip select when nokia_init() is called. If
-- used then define the following:
--    alias nokia_cs         is pin_c1    --  assign nokia chip select
--    pin_c1_direction = output

pin_b6_direction = output
pin_b4_direction = output
pin_c2_direction = output
pin_c0_direction = output

-- include glcd_6x8_font
include glcd_nokia_5110
nokia_init()

include glcd_common
include delay
include print
include glcd_5x7_font
include glcd_font

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Filled oval 84 x 48
const byte oval[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0xC0, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xF8, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE,
    0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xC0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFE, 0xFC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x1F,
    0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
    0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,
    0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[], byte in x_size, byte in y_size) is
   glcd_clear_cache()
   nokia_clear_screen()
   glcd_draw_image(image,0,0,x_size,y_size)
   glcd_cache_update()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   glcd_clear_cache()
   nokia_clear_screen()
     for 3 loop
      glcd_draw_image(battery_00,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_25,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_50,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   glcd_clear_cache()
   nokia_clear_screen()
    for 4 loop
      glcd_draw_image(envelope,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(envelope,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
    end loop
end procedure

-- Default pen color.
glcd_pen_color = GLCD_BLACK
glcd_font_use(FONT_5X7)
print_string(glcd,"Image demo !")
delay_1s(2)

forever loop

   -- Draw the images, one default, one inverted.
   draw_an_image(jal_logo,84,48)
   draw_an_image(marilyn,84,48)
   draw_an_image(oval,84,48)
   -- Show the battery charging.
   draw_battery_charging()
   -- Show drawing 2 icons dranw independently.
   draw_two_icons()

   -- Now display the inverted/normal image.
    if (glcd_pen_color == GLCD_BLACK)
    then
       glcd_pen_color = GLCD_WHITE
    else
       glcd_pen_color = GLCD_BLACK
    end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


glcd_clear_screen - JALlib Procedures Help

glcd_clear_screen JALLIB PROCEDURE

Signature

procedure glcd_clear_screen() is

Description

Purpose: Clear screen and character position to the upper left corner (0,0)
Arguments: none
Notes: When block writes are not supported by your glcd, it is highly
recommended that you define a custom glcd_clear_screen()
procedure within your glcd's library otherwise this procedure will
clear the screen pixel by pixel which is very slow.
.
Here's a list of procedures required in your glcd device library:
glcd_block_address() set start x,y and end x,y address
glcd_block_write_color() write data to each pixel in order
Also must define this constant in your glcd device library and
set your most efficient font type.
const GLCD_BLOCK_WRITE_TYPE = FONT_TOP_LEFT_HORIZONTAL

Include

To use this procedure, include the library:

include glcd_common

Parameters

None

Return Value

None

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_common.jal - JALLIB Library Documentation

glcd_common.jal JALLIB LIBRARY

Title

glcd_common - generic routines for graphic lcd

Author

Stef Mientki, Serkan Ayyldz Copyright (c) 2006..2022, all rights reserved., Adapted-by: Joep Suijs, Matthew Schinkel, Rob Hamerling, Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Generic routines for graphic lcds
glcd_line
glcd_box
glcd_box_fill
glcd_ellipse
glcd_circle
glcd_draw_image
.
Defines a common API, a common interface, where several parameters and
procedures remain device specific and should be implemented in device library.
Once interface is implemented, many features come for "free".
This common API is defined in glcd_common.jal and glcd_font.jal
.
In order to honor this common interface, and benefit its features,
the following must be implemented in the device specific library.
* GLCD_X_PIXELS: (const) specifies display's width in pixels
* glcd_display_y_size: (const) specifies display's height in pixels
* GLCD_COLOR_BITS: (const) specifies the number of bits required
for colors (1 for black & white), (16 for 16 bit color)
* glcd_pen_color: (var|const) specifies color of the pen
* glcd_background_color: (var|const) specifies the background color
* glcd_write_char(x,y,char): (proc) draw "char" at position (x,y). If no
glcd_write_char is defined in the device specific library, pixel by
pixel method will be used by default for glcd_font.jal.
* glcd_write_pixel(x,y): (proc) assuming pen and background color
previously set, draw a pixel at position (x,y) using defined colors.
This is the main procedure used by pixel-related features, like drawing
a line, circle, etc... In some cases, where glcd_write_char() can't be
used glcd_write_pixel() can also be used to draw chars. If not
implemented pixel-related features won't be available.
.
The device library or user program may also specify:
* GLCD_CLIPPING: (const) specifies if clipping is desired.
TRUE means that pixels of an ellipse beyond display
boundaries will not be sent to the display
(thus not shown on the wrong places).
When not declared, or set FALSE, no clipping is
performed and pixels may be written at unexpected
places.

Notes

Changes by Rob Hamerling (Nov/Dec 2011):
- fixed typo in comments above (GLCD_Y_SIZE -> glcd_display_y_size)
- corrected irrelevant comments (artifacts of older versions)
- changed sword to sbyte*3 of local variables in glcd_ellipse procedure
to prevent overflow of intermediate results.
- added [optional] clipping of pixels (of ellipse) when attempting
to draw beyond display boundaries
- fixed glcd_box_fill() for situation y1 < y0
- minor code optimizations (incl some add/remove pragma inline)
- comments: extended, corrected, aligned
RJ: Note that the procedure glcd_write_char_pbp() has been adapted
to deal with larger fonts but only for font that are oriented
as FONT_TOP_LEFT_HORIZONTAL, not for FONT_BOTTOM_LEFT_VERTICAL.
There where no fonts for the later to test with. So still to do.

--------------------------------------------------------------
Defining default constants when not defined by user
and defining constants derived from these.
Note: For documentation generation the constants must be
declared without indention and the description must
appear immediately ahead of it.
--------------------------------------------------------------
set width of pixel x,y variables
Width of the variables for x-coordinates

Constants and Variables

GLCD_BACKGROUND_COLOR - const byte = 0 -- background color
background color
dx - var sword = sword(x1) - sword(x0)
dy - var sword = sword(y1) - sword(y0)
two_ds - var sword = dx + dx
two_dy - var sword = dy + dy
currentx - var sword = sword(x0), currenty = sword(y0)
xinc - var sword = 1, yinc = 1
i - var word
location1 - var word = i*2+1
location2 - var word = i*2
color - var word

Routines

  • glcd'put - Procedure
  • glcd_box - Procedure
  • glcd_box_fill - Procedure
  • glcd_char_goto - Procedure
  • glcd_circle - Procedure
  • glcd_clear_screen - Procedure
  • glcd_draw_image - Procedure
  • glcd_ellipse - Procedure
  • glcd_line - Procedure
  • glcd_write_char_block - Procedure
  • glcd_write_char_pbp - Procedure


glcd_digits.jal - JALLIB Library Documentation

glcd_digits.jal JALLIB LIBRARY

Title

Library to display large numbers on a GLCD

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library draws large seven-segment like numbers on a glcd.
Large text takes a long time to draw if the font lib is used.
This is a faster since Seven-Segment like numbers can be drawn
easily using lines, and if a new number to be drawn is neairly
the same some digits do not need to be re-drawn.

Constants and Variables

glcd_digits_num_step - var byte = 0
glcd_digits_step_sets - var byte = 0
glcd_digits_step - var byte = 0

Routines

  • _glcd_digits_draw_digit'put - Procedure
  • _glcd_digits_led_a - Procedure
  • _glcd_digits_led_b - Procedure
  • _glcd_digits_led_c - Procedure
  • _glcd_digits_led_d - Procedure
  • _glcd_digits_led_e - Procedure
  • _glcd_digits_led_f - Procedure
  • _glcd_digits_led_g - Procedure
  • _glcd_digits_line - Procedure
  • glcd_digits'put - Procedure


glcd_draw_image - JALlib Procedures Help

glcd_draw_image JALLIB PROCEDURE

Signature

procedure glcd_draw_image(byte in image[],

Description

Purpose: Draw an image from a byte array.
Arguments: - image (byte array)
- x- and y-coordinates in pixels of upper left corner of the image
- width and height in pixels of the image
Notes: Same requirements as lcd_clear_screen(),
You can currently only draw an image that contains
the same number of colors as your glcd supports.

Include

To use this procedure, include the library:

include glcd_common

Parameters

None

Return Value

None

Example

From sample file: 18f4550_glcd_nokia_5110_image.jal

-- Title: GLCD Nokia 3310/5110 image demo sample. Drawing images.
-- Author: Rob Jansen, Copyright (c) 2021..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD for the Nokia 5110 display.
--              It demonstrates  the drawing of images on the display including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 84 x 48 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--

include 18f4550
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL
pragma target WDT       control    -- watchdog
pragma target LVP       enabled    -- use low Voltage Programming
pragma target MCLR      external   -- reset externally
WDTCON_SWDTEN = off                -- no watchdog

enable_digital_io()

-- Pin assignment for the Nokia display.
alias nokia_sclk       is pin_b6    --  assign nokia clock
alias nokia_sda        is pin_b4    --  assign nokia serial data in
alias nokia_res        is pin_c0    --  assign nokia reset
alias nokia_dc         is pin_c2    --  assign nokia data/commant
-- The chip select for the Nokia can be connected to ground to save a pin. If
-- to be controlled by the library then it can be defined here but all the
-- library does is enable the chip select when nokia_init() is called. If
-- used then define the following:
--    alias nokia_cs         is pin_c1    --  assign nokia chip select
--    pin_c1_direction = output

pin_b6_direction = output
pin_b4_direction = output
pin_c2_direction = output
pin_c0_direction = output

-- include glcd_6x8_font
include glcd_nokia_5110
nokia_init()

include glcd_common
include delay
include print
include glcd_5x7_font
include glcd_font

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Filled oval 84 x 48
const byte oval[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0xC0, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xF8, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE,
    0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xC0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFE, 0xFC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x1F,
    0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
    0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,
    0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[], byte in x_size, byte in y_size) is
   glcd_clear_cache()
   nokia_clear_screen()
   glcd_draw_image(image,0,0,x_size,y_size)
   glcd_cache_update()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   glcd_clear_cache()
   nokia_clear_screen()
     for 3 loop
      glcd_draw_image(battery_00,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_25,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_50,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   glcd_clear_cache()
   nokia_clear_screen()
    for 4 loop
      glcd_draw_image(envelope,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(envelope,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
    end loop
end procedure

-- Default pen color.
glcd_pen_color = GLCD_BLACK
glcd_font_use(FONT_5X7)
print_string(glcd,"Image demo !")
delay_1s(2)

forever loop

   -- Draw the images, one default, one inverted.
   draw_an_image(jal_logo,84,48)
   draw_an_image(marilyn,84,48)
   draw_an_image(oval,84,48)
   -- Show the battery charging.
   draw_battery_charging()
   -- Show drawing 2 icons dranw independently.
   draw_two_icons()

   -- Now display the inverted/normal image.
    if (glcd_pen_color == GLCD_BLACK)
    then
       glcd_pen_color = GLCD_WHITE
    else
       glcd_pen_color = GLCD_BLACK
    end if

end loop

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_ellipse - JALlib Procedures Help

glcd_ellipse JALLIB PROCEDURE

Signature

procedure glcd_ellipse(byte*GLCD_X_SIZE in cx, byte*GLCD_Y_SIZE in cy,

Description

Purpose: Draw an ellipse (Bresenham plot)
Arguments: cx, cy -> center of the ellipse in pixels
xradius, yradius -> x & y radii of the ellipse in pixels
Notes: Using actual pixel color
Would be nice to draw filled ellipses too :-)
Author Paul D'haene

Include

To use this procedure, include the library:

include glcd_common

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_font.jal - JALLIB Library Documentation

glcd_font.jal JALLIB LIBRARY

Title

FONT library for use with GLCD's

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2022, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Main font library.
API: include as many font library as you want, then include this one.
Define which font you want to use during programm execution, calling
glcd_font_use(font_id). Font lookup (retrieving a char) is done using
glcd_font_lookup(idx)

Notes

Fonts have an ID, unique amongst all font libraries. ID goes from
0x01 to 0xFE (0x00 and 0xFF are reserved for internal usage). Fonts which
are part of jallib distribution have their ID starting from 0x01,
increasing. There are also "slots" for user-defined libraries, starting from
0xFE, decreasing. This way all jallib IDs are consecutive, so are user-defined.
This leaves room for 253 fonts. Each font library addition involves updating
procedures glcd_font_use() and glcd_font_lookup().
--
Font name usually includes information about its Width x Height (eg. FONT_5X7).
A font library often declares characters, but can also declares other kind of
stuff (like sprites).
--
Example: FONT_9X12_TOP_RIGHT_HORIZONTAL_MY_FONT_NAME
--
Your lcd will most likely only support one font bit order.
--
This example is 9x12 (font_top_right_horizontal)
const byte FONT_9x12_0_NONAME[] = {0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00} -- "!"
---horizontal--->
0 0 0 0 0 0 0 0 0 -- 0x00 0x00
0 0 0 0 0 0 0 0 0 -- 0x00 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 0 0 0 0 0 0 0 -- 0x00 0x00
0 0 1 0 0 0 0 0 0 -- 0x20 0x00
0 0 0 0 0 0 0 0 0 -- 0x00 0x00
0 0 0 0 0 0 0 0 0 -- 0x00 0x00
--
This example is FONT_9x12_7_NONAME (FONT_BOTTOM_LEFT_VERTICAL)
const byte font_table[] = {0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x2F0C 0x0000 0x0000} -- "!"
--
0 0 0 0 0 0 0 0 0 ^
0 0 0 0 0 0 0 0 0 |
0 0 1 0 0 0 0 0 0 L
0 0 1 0 0 0 0 0 0 A
0 0 1 0 0 0 0 0 0 C
0 0 1 0 0 0 0 0 0 I
0 0 1 0 0 0 0 0 0 T
0 0 1 0 0 0 0 0 0 R
0 0 0 0 0 0 0 0 0 E
0 0 1 0 0 0 0 0 0 V
0 0 0 0 0 0 0 0 0 |
0 0 0 0 0 0 0 0 0 |
0x0000 0x0000 0x2F0C 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000

Sources

http://www.divshare.com/download/11463401-4a9

flag: do we use font & chars related features ?

Constants and Variables

GLCD_FONT_USAGE - const bit = true
glcd_font_current_id_ - var byte
glcd_font_current_byte_per_char_ - var byte
glcd_font_current_width_ - var byte
glcd_font_current_height_ - var byte
glcd_font_current_bit_direction_ - var byte
FONT_BIT_DIRECTION - const byte = FONT_TOP_RIGHT_VERTICAL

Routines

  • glcd_font_lookup - Function returns byte
  • glcd_font_use - Procedure


glcd_font_use - JALlib Procedures Help

glcd_font_use JALLIB PROCEDURE

Signature

procedure glcd_font_use(byte in font_id) is

Description

No description available.

Include

To use this procedure, include the library:

include glcd_font

Parameters

  • font_id - byte in

Return Value

None

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_font.jal


glcd_ili9341.jal - JALLIB Library Documentation

glcd_ili9341.jal JALLIB LIBRARY

Title

Library for GLCD using the ILI9341 display controller.

Author

Rob Jansen, Copyright (c) 2022..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Text and graphics library for the graphic display module using
the ILI9341 display controller, controlled via a 4-wire SPI
interface. The library supports displays with a resolution of
240 x 320 pixels. The default resolution can be overruled.

Notes

The default display resolution is 240 x 320 pixels If a display with a
different resolution is used you can overrule these as follows (example):
const word ILI9341_MAX_X_PIXELS = 128 -- Width
const word ILI9341_MAX_Y_PIXELS = 160 -- Height
Depeding on the display mirroring may be needed. Options available:
const ILI9342_MIRROR_X = TRUE -- Will mirror in the x-direction
const ILI9342_MIRROR_Y = TRUE -- Will mirror in the y-direction
It is also possible to dynamically change the mirroring for displays
that are assembled differently. In that case use these procedures:
-) ili9341_mirror_x_on(), ili9341_mirror_x_off()
-) ili9341_mirror_y_on(), ili9341_mirror_y_off()
After calling one of these procedures you must call the procedure:
-) ili9341_set_display_rotation() to activate the mirroring.
The following interface aliases pins must be defined by the main
program. This library uses the SPI interface which must be
initialized with SPI_MODE_00 or SPI_MODE_11:
-) alias ili9341_spi_host -- E.g. spi_master_hw, spi_master_hw2
-) alias ili9341_csn -- CS of ILI9341
-) alias ili9341_dc_rs -- DC/RS of ILI9341
Optional: Hardware reset pin. If not defined, software reset will
be used. Signal is active low.
-) alias ili9341_res -- RESET of ILI9341
If not defined the RES pin of the module must be connected to another
reset circuit. It is active low.
The user must set the direction of these pins.
About the pixel colors:
The 4-line SPI interface uses 16 bits/pixel for RGB, the format
RGB 5-6-5 is used which means 5 bits for red, 6 bits for green and
5 bits for blue, See specification page 63:
16 bit/pixel color order (R:5-bit, G:6-bit, B:5-bit)

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Number of pixels on the ILI9341 screen. The user can overrule these for
displays with another resolution.

Sources

a-Si TFT LCD Single Chip Driver 240RGBx320 Resolution and 262K color
Specification version: V1.09
Inspired by the Adafruit ILI9341 library for Arduino.

Constants and Variables

ILI9341_MAX_X_PIXELS - const word = 240 -- Default width
Default width
ILI9341_MAX_Y_PIXELS - const word = 320 -- Default height
Default height
ILI9341_BLACK - const word = 0x0000 -- 0, 0, 0
0, 0, 0
ILI9341_NAVY - const word = 0x000F -- 0, 0, 123
0, 0, 123
ILI9341_DARKGREEN - const word = 0x03E0 -- 0, 125, 0
0, 125, 0
ILI9341_DARKCYAN - const word = 0x03EF -- 0, 125, 123
0, 125, 123
ILI9341_MAROON - const word = 0x7800 -- 123, 0, 0
123, 0, 0
ILI9341_PURPLE - const word = 0x780F -- 123, 0, 123
123, 0, 123
ILI9341_OLIVE - const word = 0x7BE0 -- 123, 125, 0
123, 125, 0
ILI9341_LIGHTGREY - const word = 0xC618 -- 198, 195, 198
198, 195, 198
ILI9341_DARKGREY - const word = 0x7BEF -- 123, 125, 123
123, 125, 123
ILI9341_BLUE - const word = 0x001F -- 0, 0, 255
0, 0, 255
ILI9341_GREEN - const word = 0x07E0 -- 0, 255, 0
0, 255, 0
ILI9341_CYAN - const word = 0x07FF -- 0, 255, 255
0, 255, 255
ILI9341_RED - const word = 0xF800 -- 255, 0, 0
255, 0, 0
ILI9341_MAGENTA - const word = 0xF81F -- 255, 0, 255
255, 0, 255
ILI9341_YELLOW - const word = 0xFFE0 -- 255, 255, 0
255, 255, 0
ILI9341_WHITE - const word = 0xFFFF -- 255, 255, 255
255, 255, 255
ILI9341_ORANGE - const word = 0xFD20 -- 255, 165, 0
255, 165, 0
ILI9341_GREENYELLOW - const word = 0xAFE5 -- 173, 255, 41
173, 255, 41
ILI9341_PINK - const word = 0xFC18 -- 255, 130, 198
255, 130, 198
GLCD_X_PIXELS - const byte = ILI9341_MAX_X_PIXELS
GLCD_Y_PIXELS - const word = ILI9341_MAX_Y_PIXELS
GLCD_COLOR_BITS - const byte = 16 -- 16 bit colors
16 bit colors
glcd_background_color - var word = ILI9341_BLACK
glcd_pen_color - var word = ILI9341_WHITE
FONT_AUTO_WRAP - const bit = TRUE
MADCTL_MX_LR - const byte = 0x00 -- Left to Right
Left to Right
MADCTL_MX_RL - const byte = 0x40 -- Right to left (default for module MSP2401)
Right to left (default for module MSP2401)
MADCTL_MY_BT - const byte = 0x80 -- Bottom to top
Bottom to top
MADCTL_MY_TB - const byte = 0x00 -- Top to bottom (default for module MSP2401)
Top to bottom (default for module MSP2401)
MADCTL_MV - const byte = 0x20 -- Reverse Mode (swap x and y)
Reverse Mode (swap x and y)
MADCTL_BGR - const byte = 0x08 -- Blue-Green-Red pixel order (bit 3 = 1)
Blue-Green-Red pixel order (bit 3 = 1)
data - var word

Routines

  • _ili9341_read_word - Function returns word
  • _ili9341_set_address_window - Procedure
  • _ili9341_start_transmission - Procedure
  • _ili9341_stop_transmission - Procedure
  • _ili9341_write_command - Procedure
  • _ili9341_write_data_byte - Procedure
  • _ili9341_write_data_word - Procedure
  • _ili9341_write_word - Procedure
  • ili9341_clear_screen - Procedure
  • ili9341_display_inverse - Procedure
  • ili9341_display_normal - Procedure
  • ili9341_display_off - Procedure
  • ili9341_display_on - Procedure
  • ili9341_display_sleep - Procedure
  • ili9341_display_wakeup - Procedure
  • ili9341_draw_image - Procedure
  • ili9341_fill_screen - Procedure
  • ili9341_goto - Procedure
  • ili9341_init - Procedure
  • ili9341_mirror_x_off - Procedure
  • ili9341_mirror_x_on - Procedure
  • ili9341_mirror_y_off - Procedure
  • ili9341_mirror_y_on - Procedure
  • ili9341_reset - Procedure
  • ili9341_set_display_rotation - Procedure
  • ili9341_set_vertical_scroll_area - Procedure
  • ili9341_vertical_scroll_display - Procedure
  • ili9341_write_pixel - Procedure


glcd_init - JALlib Procedures Help

glcd_init JALLIB PROCEDURE

Signature

procedure glcd_init() is

Description

Purpose: Initialize the graphic LCD.
Arguments: none
Notes: to be called before using any other GLCD function.

Include

To use this procedure, include the library:

include glcd_ks0108

Parameters

None

Return Value

None

Example

From sample file: 18f6310_glcd_ks0108.jal

-- ------------------------------------------------------
-- Title: Graphics LCD sample of the Microchip pic18f6310
--
-- Author: Rob Hamerling, Copyright (c) 2011..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample program for use with 128x64 graphics LCD
-- with KS0108 chipset, like the GDM12864A, using external fonts.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 18f6310

pragma target clock   20_000_000                   -- Fosc

pragma target OSC     hs
pragma target FCMEN   disabled
pragma target IESO    disabled
pragma target WDT     control
pragma target CCP2MUX pin_C1
pragma target MCLR    external
pragma target DEBUG   disabled

WDTCON_SWDTEN = OFF                    -- no watchdog

-- GRAPHIC_LCD IO definition ------------------------
var volatile byte GLCD_DATAPRT     is portD
var volatile byte GLCD_DATAPRT_DIR is portD_direction

var volatile bit GLCD_DI  is pin_E7
var volatile bit GLCD_RW  is pin_E3
var volatile bit GLCD_E   is pin_E5
var volatile bit GLCD_CS1 is pin_B0
var volatile bit GLCD_CS2 is pin_B1
var volatile bit GLCD_RST is pin_B2

var volatile bit GLCD_DI_DIRECTION  is pin_E7_direction
var volatile bit GLCD_RW_DIRECTION  is pin_E3_direction
var volatile bit GLCD_E_DIRECTION   is pin_E5_direction
var volatile bit GLCD_CS1_DIRECTION is pin_B0_direction
var volatile bit GLCD_CS2_DIRECTION is pin_B1_direction
var volatile bit GLCD_RST_DIRECTION is pin_B2_direction

const GLCD_CLIPPING = TRUE                         -- enable clipping (of ellipse)

enable_digital_io()                                -- all pins digital I/O

include delay
include math
include print

include glcd_6x8_font                              -- font to be used
include glcd_font                                  -- common font stuff
glcd_font_use(FONT_6X8)                            -- activate font

include glcd_ks0108                                -- glcd device dependent library

glcd_init()                                        -- initialize display

const byte str[] = "GLCD_TEST "

glcd_background_color = GLCD_WHITE                 -- background color
glcd_pen_color = GLCD_BLACK                        -- pixel color

var byte i = 0
var byte d

forever loop

   glcd_clear_screen()
   delay_100ms(10)

   for (GLCD_X_PIXELS / glcd_font_current_width_ + 1) using i loop
      glcd_write_char(i * glcd_font_current_width_, i, "A" + i)   -- every char 1 pixel-line lower
      delay_100ms(1)
   end loop

   for (GLCD_X_PIXELS / glcd_font_current_width_ + 1) using i loop
      glcd_write_char(i * glcd_font_current_width_, 12 + i, "a" + i)  -- every char 1 pixel-line lower
      delay_100ms(1)
   end loop

-- Test to see if reads work also properly

-- for (GLCD_X_PIXELS - 1) using i loop
--    d = _ks0108_read_byte(i, 8)                  -- page boundary: simple read
--    _ks0108_write_byte(i, 44, d)
-- end loop
--
-- for (GLCD_X_PIXELS - 1) using i loop
--    d = _ks0108_read_byte(i, 12)                 -- page crossing: double read
--    _ks0108_write_byte(i, 56, d)
-- end loop

   delay_100ms(50)

end loop

Generated by JALlib CHM Help System | Source: glcd_ks0108.jal


glcd_ks0108.jal - JALLIB Library Documentation

glcd_ks0108.jal JALLIB LIBRARY

Title

glcd_ks0108 - Library for KS0108 compatible graphic LCDs

Author

Serkan Ayyldz Copyright (c) 2006..2009, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for KS0108 compatible graphic lcds with 128x64 resolution
for example the GDM12864A.

Notes

Modifications by Rob Hamerling (nov/dec 2011):
- Minor timing changes in ks0108_read_() and ks0108_write_()
according to datasheet schemes for MPU Write timing and Read timing.
Replaced hard coded ASM NOPs by _usec_delay()
- Private procedures/function prefixed with underscore
- Added procedure glcd_clear_screen() and use it in glcd_init().
Uses the reset line to set Z-address to zero.
- Modified procedures to be able to write characters with
y-coordinates NOT on page (8-bit) boundaries.
Works probably only with max 8 bits high font (5x7 and 6x8)
- Replaced absolute values for loops and offsets by symbolic values
- Code optimisations, incl add/remove of some 'pragma inline'
- Fixed some bugs with external fonts
- Comments extended, corrected, aligned (for JALAPI docs)
Modifications by Rob Hamerling (May 2015)
- Added procedure to support remap (reverse) databit sequence
for more wiring flexibility (pin sequence: D7..D0 in stead of D0..D7)
Controlled by constant GLCD_REVERSE_DATABITS = FALSE / TRUE.
.
Technical (library internal) details
- A 128x64 graphic LCD consists with 2 controllers (KS0108_LEFT and
KS0108_RIGHT), each take care of 64x64 bits.
- Addressing: upper left corner is coordinate (0,0)
- A byte of data represents a column of 8 pixels, so the vertical
64 pixels are represented by 8 bytes (a row of 8 bits is called
'page' in the datasheet).
----------------------------------------------------------------------------

Constants and Variables

GLCD_X_PIXELS - const byte = 128 -- display x-dimension
display x-dimension
GLCD_Y_PIXELS - const byte = 64 -- display y-dimension
display y-dimension
GLCD_COLOR_BITS - const byte = 1 -- monochrome display
monochrome display
KS0108_LEFT - const bit = 0 -- select left part of display
select left part of display
KS0108_RIGHT - const bit = 1 -- select right part of display
select right part of display
KS0108_CMD_ON - const byte = 0x3F -- command to enable the display
command to enable the display
KS0108_CMD_OFF - const byte = 0x3E -- command to disable the display
command to disable the display
KS0108_CMD_PAGE - const byte = 0xB8 -- command to select page (y-coord / 8)
command to select page (y-coord / 8)
KS0108_CMD_COLUMN - const byte = 0x40 -- command to select column (x-coord)
command to select column (x-coord)
KS0108_CMD_TOP_RAM - const byte = 0xC0 -- command to set startline
command to set startline
GLCD_BLACK - const byte = 0x01 -- normal pen color
normal pen color
GLCD_WHITE - const byte = 0x00 -- alternate pen color
alternate pen color
GLCD_DI_DATA - const byte = high -- select data to display
select data to display
GLCD_DI_INST - const byte = low -- select command
select command
glcd_background_color - var byte = GLCD_WHITE -- default background color
default background color
glcd_pen_color - var byte = GLCD_BLACK -- default pen color
default pen color

Routines

  • glcd_clear_screen - Procedure
  • glcd_fill - Procedure
  • glcd_init - Procedure
  • glcd_write_char - Procedure
  • glcd_write_pixel - Procedure
  • ks0108_column_ - Procedure
  • ks0108_data_ - Procedure
  • ks0108_inst_ - Procedure
  • ks0108_off_ - Procedure
  • ks0108_on_ - Procedure
  • ks0108_page_ - Procedure
  • ks0108_read_ - Function returns byte
  • ks0108_read_byte_ - Function returns byte
  • ks0108_write_ - Procedure
  • ks0108_write_byte_ - Procedure
  • ks0108_write_char_ - Procedure
  • remap_bits - Function returns byte


glcd_line - JALlib Procedures Help

glcd_line JALLIB PROCEDURE

Signature

procedure glcd_line(byte*GLCD_X_SIZE in x0, byte*GLCD_Y_SIZE in y0,

Description

Purpose: Draw a line
arguments: - x- and y-coordinates in pixels of start of line
- x- and y-coordinates in pixels of end of line
Notes : using current pixel color
Author : Paul D'haene

Include

To use this procedure, include the library:

include glcd_common

Parameters

None

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_common.jal


glcd_nokia_5110.jal - JALLIB Library Documentation

glcd_nokia_5110.jal JALLIB LIBRARY

Title

library for GLCD with pcd8544 controller used in Nokia 3310/5110

Author

Andre Miller Copyright (c) 2008..2021, all rights reserved., Adapted-by: Richard Zengerink, Sebastien Lelong, Paul D'haene, Rob Jansen

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library for Nokia 3310/5510 display with pcd8544 controller.

Sources

Data sheet PCD8544.

Constants and Variables

GLCD_X_PIXELS - const byte = 84
GLCD_Y_PIXELS - const byte = 48
GLCD_COLOR_BITS - const byte = 1 -- monochrome display
monochrome display
FONT_AUTO_WRAP - const bit = TRUE
glcd_background_color - var byte = GLCD_WHITE
glcd_pen_color - var byte = GLCD_BLACK
CACHE_SIZE - const word = word(GLCD_X_PIXELS) * word(GLCD_Y_PIXELS/8)
LARGE_ARRAY_1_SIZE - const dword = CACHE_SIZE -- number of array variables
number of array variables
LARGE_ARRAY_1_VARIABLE_SIZE - const dword = 1 -- size of variables (byte*1)
size of variables (byte*1)
glcd_lo_watermark - var word = CACHE_SIZE - 1
glcd_hi_watermark - var word = 0
glcd_cache_changed - var bit = TRUE
image_index - var word

Routines

  • _nokia_glcd_write - Procedure
  • _nokia_glcd_write_command - Procedure
  • _nokia_glcd_write_data - Procedure
  • glcd_cache_update - Procedure
  • glcd_clear_cache - Procedure
  • glcd_draw_image - Procedure
  • glcd_write_char - Procedure
  • glcd_write_pixel - Procedure
  • graphic_to_nokia - Procedure
  • nokia_clear_screen - Procedure
  • nokia_contrast - Procedure
  • nokia_goto - Procedure
  • nokia_init - Procedure


glcd_ssd1306.jal - JALLIB Library Documentation

glcd_ssd1306.jal JALLIB LIBRARY

Title

Library for GLCD using the SSD1306 display controller.

Author

Rob Jansen, Copyright (c) 2020..2025, all rights reserved., Adapted-by:

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Text and graphics library for the graphic display module using
the SSD1306 display controller. The library supports displays
with a resolution of 128 x 32 or 128 x 64 (default).

Notes

This library supports the control of the display via one of two
interfaces IIC or 4-wire SPI which depends on the interface that is
included by the main program before including this library.
This library supports control of the module using I2C software,
I2C hardware, I2C hardware2, SPI hardware and SPI hardware2.
Next to that the user can select a software SPI interface. In order
to use this define the following:
-) const SSD1306_SOFTWARE_SPI = TRUE
The default display pixel size is 128 x 64 but can be changed to
128 x 32 using the following:
-) const SSD1306_Y_32_PIXELS = TRUE
The main program must include the required interface library and
initialize it.
-) For IIC the maximum clock is 400 kHz.
-) For SPI use SPI_MODE_00 with a maximum clock of 10 MHz.
For IIC, the main program has to define the required IIC pins.
Nex to that the following SPI pins must be defined by the main
main before including this library.
Only when using SSD1306_SOFTWARE_SPI:
-) alias ssd1306_sck -- For SPI to D0 of SSD1306.
-) alias ssd1306_sck_direction
-) alias ssd1306_sdo -- For SPI to D1 of SSD1306.
-) alias ssd1306_sdo_direction
Additonal Required pins:
-) alias ssd1306_csn -- For SPI to CS of SSD1306.
-) alias ssd1306_csn_direction
-) alias ssd1306_dc -- For SPI to CS of SSD1306.
-) alias ssd1306_dc_direction
The SPI version of the SSD1306 uses a hardware reset pin for its reset.
This optional feature can be used by defining the following: pin
-) alias ssd1306_res -- For SPI to RES of SSD1306.
-) alias ssd1306_res_direction
If not defined the RES pin of the module must be connected to another
reset circuit. It is active low.
This graphic display library needs quite a large data space for
maintaining a cache. The PIC must have more than 1024 bytes of data
memory available as to be able to use the grapics features.
If only text needs to be displayed, this cache is not needed. The
text only use can be enabled by defining the following:
-) const SSD1306_TEXT_ONLY = TRUE
When using a bigger (>8 pixels in height) horizontal oriented
character font, a character buffer is needed with the size of the
used font, also see FONT_xxxx_BYTE_PER_CHAR in the font library you
are using. The default size of this buffer is 64 bytes and can be
reduced to save data space if a smaller font, or no font, is used.
For example the 12x16 horizontal font uses 32 bytes for one character
and so we can set the character buffer to this size by:
-) const SSD1306_CHAR_BUFFER_SIZE = 32
If no buffer is used (e.g. for vertical oriented fonts), you can set
the miniumum size to 1, saving data space.
The default IIC address can be overruled by defining it in the main
program. Note that this is not needed since the default is already set
to the default module IIC address of 0b0111_1000:
-) const byte SSD1306_IIC_ADDRESS = <IIC Address>
-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Number of pixels on the screen. Number of Y pixels is default 64 but can be
changed to 32 pixels.

Sources

Library glcd_nokia_5110.jal used as starting point.
SS1306 Data Sheet Revision 1.1 (April 2008)
Adafruit_SSD1306 library and some others.

Constants and Variables

SSD1306_MAX_X_PIXELS - const byte = 128 -- 0..127
0..127
SSD1306_MAX_Y_PIXELS - const byte = 32 -- 0..31
0..31
SSD1306_MAX_Y_PIXELS - const byte = 64 -- 0..63
0..63
SSD1306_IIC_ADDRESS - const byte = 0b0111_1000
GLCD_X_PIXELS - const byte = SSD1306_MAX_X_PIXELS
GLCD_Y_PIXELS - const byte = SSD1306_MAX_Y_PIXELS
GLCD_COLOR_BITS - const byte = 1 -- Monochrome display.
Monochrome display.
glcd_background_color - var byte = GLCD_WHITE
glcd_pen_color - var byte = GLCD_BLACK
FONT_AUTO_WRAP - const bit = TRUE
CACHE_SIZE - const word = word(GLCD_X_PIXELS) * word(GLCD_Y_PIXELS/8)
LARGE_ARRAY_1_SIZE - const dword = CACHE_SIZE -- number of array variables
number of array variables
LARGE_ARRAY_1_VARIABLE_SIZE - const dword = 1 -- size of variables (byte*1)
size of variables (byte*1)
glcd_lo_watermark - var word = CACHE_SIZE - 1 -- Points to start of write area.
Points to start of write area.
glcd_hi_watermark - var word = 0 -- Points to end of write area.
Points to end of write area.
glcd_cache_changed - var bit = TRUE
image_index - var word

Routines

  • _ssd1306_spi_sw_exchange - Function returns byte
  • _ssd1306_start_transmission - Procedure
  • _ssd1306_stop_transmission - Procedure
  • _ssd1306_write_byte - Procedure
  • _ssd1306_write_one_data_byte - Procedure
  • glcd_clear_cache - Procedure
  • ssd1306_clear_screen - Procedure
  • ssd1306_display_all_on - Procedure
  • ssd1306_display_inverse - Procedure
  • ssd1306_display_normal - Procedure
  • ssd1306_display_off - Procedure
  • ssd1306_display_on - Procedure
  • ssd1306_display_resume - Procedure
  • ssd1306_draw_image - Procedure
  • ssd1306_goto - Procedure
  • ssd1306_init - Procedure
  • ssd1306_send_command - Procedure
  • ssd1306_send_command_parameter - Procedure
  • ssd1306_set_contrast - Procedure
  • ssd1306_set_start_line - Procedure
  • ssd1306_start_scroll_diagonal_left - Procedure
  • ssd1306_start_scroll_diagonal_right - Procedure
  • ssd1306_start_scroll_left - Procedure
  • ssd1306_start_scroll_right - Procedure
  • ssd1306_stop_scroll - Procedure
  • ssd1306_update_display - Procedure
  • ssd1306_write_char - Procedure
  • ssd1306_write_pixel - Procedure
  • ssd1306_write_pixel - Procedure


glcd_t6963.jal - JALLIB Library Documentation

glcd_t6963.jal JALLIB LIBRARY

Title

Character/graphic LCD with Toshiba T6963C controller

Author

Rob Hamerling, Copyright (c) 2015-2015, all rights reserved, Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to handle character/graphics LCD with Toshiba T6963c controller
Tested with thi following modules:
TW-7894V-0 (120x64)
MG2406G (240x64)
MTG-2460G (240x64)
.
The t6963 ia a rather special glcd controller: it supports an LCD as
text and as graphics display simultaneously and independently.
.
Connector pins of these modules:
pin symb I/O description
1 FG frame ground
2 GND ground
3 VCC lcd logic voltage
4 VEE lcd (contrast) voltage
5 wr O write enable (L)
6 rd O read enable (L)
7 ce O chip enable (L)
8 cd O H: command, L: data
9 not connected
10 reset O reset (L)
11-18 db0-7 I/O data byte
19 fs O font select (H: 6X8, L: 8x8)
20 not connected
Other modules may have a different pin layout!
Of the TW-7894V-0 pin 19 seems not connected: fixed 6x8 font.
Of the MG2406G pin 9 is Vee: negative voltage for LCD contrast.
.
The following aliases must be defined by the user program:
.
Data port:
alias t6963_dataport is portX
alias t6963_dataport_direction is portX_direction
The library requires that all 8 data pins are wired to the
same PIC-port and in sequence 'd0' to pin_X0, 'd1' to pin_X1, etc.
All pins must be capable of digital output and input.
The port direction is dynamically selected by the library.
.
Control pins:
alias t6963_wr is pin_Ya -- write enable
alias t6963_rd is pin_Yb -- read enable
alias t6963_cd is pin_Yc -- command or data selection
alias t6963_ce is pin_Yd -- chip enable
alias t6963_reset is pin_Ye -- reset controller
alias t6963_fs is pin_Yf -- font select
The control pins may be connected to any pin of the PIC capable
of digital output and must be set for output by the user program.
The font selection pin of the glcd module may be hard wired or the module
may have a fixed font width. In that case the specification of t6963_fs
is not required.
.
The following constant declarations are required:
const byte T6963X_PIXELS = 120 )
const byte T6963Y_PIXELS = 64 ) example values
const byte T6963_FONT_WIDTH = 6 )
T6963_FONT_WIDTH is optional, when not specified an 6 pixels wide font is assumed.
Remarks: - The line length is derived from X-pixels and font width.
The T6963c performs auto-wrapping of text and attributes based
on this line length.
- When the specified font width does not match with the hardware
you may not see what you expected to see.
For graphics display the following constants and variables may be needed:
const bit T6963_CLIPPING = TRUE (default is FALSE)
var bit t6963_pen_color = ON (default, OFF = clear pixel)
.
T6963c memory organisation as used by this library.
+-----------------------+ 0x0000
| |
| Text Space |
| (2 KB) |
+ ----------------------+ 0x0800
| |
| Graphics Space |
| (4 KB) |
| |
+-----------------------+ 0x1800
| CG area (2KB) |
+-----------------------+ 0x2000
This memory layout is (temporary) fixed as ths proved to work fine
with the tested modules.
However this may be a limitation for more fancy applications!
Modules can have up to 64 KB of memory. A probe function to determine
the actual amount of RAM is already present, but not activated
bacause it didn't work properly with a module with 64 KB RAM.
.
Public procedures and functions:

Constants and Variables

6963_FONT_WIDTH - const byte = 6
t6963_pen_color - var bit = ON -- default: pixel on
default: pixel on
T6963_CLIPPING - const bit = FALSE -- default: may show stray pixels
default: may show stray pixels
T6963_GRAPHICS_AREA - const byte = T6963_X_PIXELS / T6963_FONT_WIDTH
T6963_TEXT_AREA - const byte = T6963_X_PIXELS / T6963_FONT_WIDTH
T6963_TEXT_ROWS - const byte = T6963_Y_PIXELS / 8
T6963_TEXT_HOME - const word = 0x0000 -- fixed
fixed
t6963_memsize - var word = 0x2000 -- 8 KB
8 KB
t6963_graphics_home - var word = 0x0800 -- +2 KB
+2 KB
t6963_cg_home - var word = 0x1800 -- +6 KB
+6 KB
T6963_SET_CURSOR_POINTER - const byte = 0x21
T6963_SET_OFFSET_REGISTER - const byte = 0x22
T6963_SET_ADDRESS_POINTER - const byte = 0x24
T6963_SET_TEXT_HOME_ADDRESS - const byte = 0x40
T6963_SET_TEXT_AREA - const byte = 0x41
T6963_SET_GRAPHICS_HOME_ADDRESS - const byte = 0x42
T6963_SET_GRAPHICS_AREA - const byte = 0x43
T6963_SET_MODE_OR - const byte = 0x80
T6963_SET_MODE_EXOR - const byte = 0x81
T6963_SET_MODE_AND - const byte = 0x83
T6963_SET_MODE_TEXT_ONLY - const byte = 0x84
T6963_SET_MODE_CG_EXTERNAL - const byte = 0x88
T6963_ATTRIBUTE_NORMAL - const byte = 0x00
T6963_ATTRIBUTE_REVERSE - const byte = 0x05
T6963_ATTRIBUTE_INHIBIT - const byte = 0x03
T6963_ATTRIBUTE_NORMAL_BLINK - const byte = 0x08
T6963_ATTRIBUTE_REVERSE_BLINK - const byte = 0x0D
T6963_ATTRIBUTE_INHIBIT_BLINK - const byte = 0x0B
T6963_DISPLAY_OFF - const byte = 0x90
T6963_DISPLAY_CURSOR_BLINK_ON - const byte = 0x91
T6963_DISPLAY_CURSOR_ON - const byte = 0x92
T6963_DISPLAY_TEXT_ON - const byte = 0x94
T6963_DISPLAY_GRAPHICS_ON - const byte = 0x98
T6963_CURSOR_PATTERN_SELECT - const byte = 0xA0
T6963_DATA_AUTO_WRITE - const byte = 0xB0
T6963_DATA_AUTO_READ - const byte = 0xB1
T6963_DATA_AUTO_RESET - const byte = 0xB2
T6963_DATA_WRITE_AND_INCREMENT - const byte = 0xC0
T6963_DATA_READ_AND_INCREMENT - const byte = 0xC1
T6963_DATA_WRITE_AND_DECREMENT - const byte = 0xC2
T6963_DATA_READ_AND_DECREMENT - const byte = 0xC3
T6963_DATA_WRITE - const byte = 0xC4
T6963_DATA_READ - const byte = 0xC5
T6963_SCREEN_PEEK - const byte = 0xE0
T6963_SCREEN_COPY - const byte = 0xE8
T6963_PIXEL_CLEAR - const byte = 0xF0
T6963_PIXEL_SET - const byte = 0xF8

Routines

  • t6963_clear_graphics - Procedure
  • t6963_clear_memory_region - Procedure
  • t6963_clear_screen - Procedure
  • t6963_clear_text - Procedure
  • t6963_display_mode - Procedure
  • t6963_draw_image - Procedure
  • t6963_init - Procedure
  • t6963_probe_memory - Function returns byte
  • t6963_read_cg_memory - Procedure
  • t6963_read_char - Function returns byte
  • t6963_read_data - Procedure
  • t6963_read_dataport - Function returns byte
  • t6963_read_next_char - Function returns byte
  • t6963_set_address - Procedure
  • t6963_set_attribute - Procedure
  • t6963_set_cg_offset - Procedure
  • t6963_set_cursor_pattern - Procedure
  • t6963_set_cursor_position - Procedure
  • t6963_set_mode - Procedure
  • t6963_wait_until_ready - Procedure
  • t6963_wait_until_ready_mask - Procedure
  • t6963_wait_until_ready_to_auto_read - Procedure
  • t6963_wait_until_ready_to_auto_write - Procedure
  • t6963_write_cg_memory - Procedure
  • t6963_write_char - Procedure
  • t6963_write_command - Procedure
  • t6963_write_data - Procedure
  • t6963_write_dataport - Procedure
  • t6963_write_next_char - Procedure
  • t6963_write_pixel - Procedure
  • t6963_write_string - Procedure
  • verify - Function returns bit


glcd_touch_ads7843.jal - JALLIB Library Documentation

glcd_touch_ads7843.jal JALLIB LIBRARY

Title

Library for touch screen using an ADS7843 or XPT24046 controller.

Author

Rob Jansen, Copyright (c) 2022..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for touch screen controllers. Both ADS7843 as well as
XPT2406 controllers are supported which are compatible.

Notes

This library supports the control of the touch screen via 4-wire SPI
It uses its own software SPI since the clocking of data is done on
different edges.
The default display resolution is 240 x 320 pixels If a display with a
different resolution is used you can overrule these as follows (example):
const word ADS7843_MAX_X_PIXELS = 128 -- Width
const word ADS7843_MAX_Y_PIXELS = 160 -- Height
Depending on the display, mirroring may be needed. Available settings:
const ADS7843_MIRROR_X = TRUE -- Will mirror in the x-direction
const ADS7843_MIRROR_Y = TRUE -- Will mirror in the y-direction
The following pins must be defined by the main program before
including this library:
-) alias ads7843_sck -- To T_CLK of the touch screen
-) alias ads7843_sdo -- To T_DIN of touch screen
-) alias ads7843_sdi -- To T_DO of touch screen
-) alias ads7843_csn -- To T_CS of touch screen
The user must set the direction of these pins.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Touch screen rotation defintions in degrees. This should be used if the screen
is rotated. The touch screen has to match the screen rotation.

Sources

Texas Instruments ADS7843 Touch Screen Controller
SBAS090B – SEPTEMBER 2000 – REVISED MAY 2002

Constants and Variables

ADS7843_ROTATE_0_DEGREES - const byte = 0 -- Default.
Default.
ADS7843_ROTATE_90_DEGREES - const byte = 1
ADS7843_ROTATE_180_DEGREES - const byte = 2
ADS7843_ROTATE_270_DEGREES - const byte = 3
ADS7843_X_TOP_LEFT - const word = 0x0EE5
ADS7843_Y_TOP_LEFT - const word = 0x0F49
ADS7843_X_BOTTOM_RIGHT - const word = 0x011F
ADS7843_Y_BOTTOM_RIGHT - const word = 0x01A7
touch_to_pixel_x - var dword = 0
touch_to_pixel_y - var dword = 0

Routines

  • _ads7843_read_adc - Function returns word
  • _ads7843_spi_sw'get - Function returns byte
  • _ads7843_spi_sw'put - Procedure
  • ads7843_get_touch_coordinate - Function returns bit
  • ads7843_get_touch_coordinate_raw - Function returns bit
  • ads7843_init - Procedure
  • ads7843_set_screen_orientation - Procedure
  • ads7843_touch_to_display_coordinate - Procedure


glcd_write_char - JALlib Procedures Help

glcd_write_char JALLIB PROCEDURE

Signature

procedure glcd_write_char(byte in x, byte in y, byte in ch ) is

Description

Purpose: Same as ks0108_write_char_(), but uses external font.
Arguments: - x-coordinate (in pixels) of left most pixel columm (range 0..127)
- y-coordinate (in pixels) of upper most pixel-row (range 0..63)
- character (binary value in range 32..122)
Notes: When y-coordinate is a multiple of 8 (0,8,16,etc.): single write,
otherwise two read-modify-write cycles needed: slower!

Include

To use this procedure, include the library:

include glcd_ks0108

Parameters

  • x - byte in
  • y - byte in
  • ch - byte in

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_ks0108.jal


glcd_write_pixel - JALlib Procedures Help

glcd_write_pixel JALLIB PROCEDURE

Signature

procedure glcd_write_pixel(byte in x, byte in y) is

Description

Purpose: Write (modify) a single pixel of the display
Arguments: - x-coordinate of the pixel
- y-coordinate of the pixel

Include

To use this procedure, include the library:

include glcd_ks0108

Parameters

  • x - byte in
  • y - byte in

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_ks0108.jal


goel370.jal - JALLIB Library Documentation

goel370.jal JALLIB LIBRARY

Title

oxygen sensor, GOEL 370 by Greisinger

Author

Eur van Andel, eur@fiwihex.nl (c) 2011, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

library for calibrating and calculating GOEL370 oxygen sensor
I needed to log these sensors in an existing CAN BUS setup and made my own amplifier.

Notes

The sensor signal is 0..40mV for 0..100% Oxygen concentration.
I just amplified the sensor signal 100 times with a simple opamp circuit
to get 0..4V for 0..100% oxygen:
+5V DC
|\|
sensor #--------|+\
input | >---+-----o PIC analog input
# +-|-/ |
| | |/ |
| | ___ |
| +--|___|-+
| | 10k
| .-.
| | | 100R
| | |
| '-'
| |
=== ===
GND GND (also PIC GND)
It turns out that for different sensors, only the slope of the signal differs. So you can adjust
your amplification to your expected oxygen range for maximum resolution. Get at least three digits
for the range that you want to measure, so above 100 as analog value, which is about 0.5V

Sources

http://www.greisinger.de/ manufacturer of sensor
I contacted Greisinger and they approved the publication of this code.
http://www.tech-chat.de/aacircuit.html ASCII circuit editor for Windows

This function takes the word output of the D/A converter (0..1023) and the calibration value
it returns a word value of the oxygen concentration in % * 100. So if the oxygen concentration is
21%, the function returns 2100.

Routines

  • g370_calbr - Function returns word
  • g370_ox - Function returns word


gp2d02_read_pins - JALlib Procedures Help

gp2d02_read_pins JALLIB FUNCTION

Signature

function gp2d02_read_pins(volatile bit out pin_vin, volatile bit in pin_vout) return byte is

Description

No description available.

Include

To use this procedure, include the library:

include ir_ranger_gp2d02

Parameters

  • pin_vin - bit out
  • pin_vout - bit in

Return Value

byte - Function return value

Example

From sample file: 18f2520_ir_ranger_gp2d02.jal

-- Title: Test program for GP2D02 IR ranger
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample show how to use GP2D02 IR ranger library
-- It regularly gets distance measures, and print them back to serial.
-- It also uses a led to "show" the distance. This LED is connected to a PWM output.
-- it will be more or less bright according to the distance between the ranger
-- and an object.
-- --
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_ir_ranger_gp2d02.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog

enable_digital_io()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on()

;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- map pins
alias gp2d02_vin is pin_a4
alias gp2d02_vout is pin_a6
alias gp2d02_vin_direction is pin_a4_direction
alias gp2d02_vout_direction is pin_a6_direction

include ir_ranger_gp2d02
-- set pin direction (careful: "vin" is the GP2D02 pin's name,
-- it's an input for GP2D02, but an output for PIC !)
gp2d02_vin_direction = output
gp2d02_vout_direction = input

var byte measure
forever loop
   -- read distance from ranger num. 0
   measure = gp2d02_read_pins(gp2d02_vin,gp2d02_vout)
   -- results via serial
   serial_hw_write(measure)
   -- now blink more or less
   pwm1_set_dutycycle_ratio(measure)
end loop

Generated by JALlib CHM Help System | Source: ir_ranger_gp2d02.jal


gps_neo_6m.jal - JALLIB Library Documentation

gps_neo_6m.jal JALLIB LIBRARY

Title

Library for the GPS NEO-6M receiver.

Author

Rob Jansen, Copyright (c) 2021..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

JAL library for use of the GPS NEO-6M receiver.
This library provides the functionality to obtain the GPS time,
the GPS date and the GPS location from the GPS NEO-6M receiver.
The information is received and decoded on an interrupt basis.

Notes

The default serial interface of the NEO-6M GPS receiver is 9600 baud,
1 stopbit, no parity and no flow control.
At least one of the JAL serial hardware libraries must be included
and initialized by the main program with the above settings.

-----------------------------------------------------------------------------
-------------------------- Public API ---------------------------------------
-----------------------------------------------------------------------------
----------------------------------------------------------------------------
Initialize the GPS NEO 6M library. The peripheral interrupt and global
interrupt are enabled.
----------------------------------------------------------------------------

Sources

The NMEA 0183 Protocol. Klaus Betke, May 2000. Revised August 2001.
Also see RMC at: https://gpsd.gitlab.io/gpsd/NMEA.html

Constants and Variables

index - var byte = 0
success - var bit = FALSE

Routines

  • _gps_neo_6m_ascii_to_binary - Function returns byte
  • _gps_neo_6m_convert_gps - Function returns float
  • _gps_neo_6m_is_ascii_number - Function returns bit
  • _gps_neo_6m_serial_interrupt - Procedure
  • _gps_neo_6m_split_left_right - Function returns bit
  • gps_neo_6m_data_available - Function returns bit
  • gps_neo_6m_get_date - Procedure
  • gps_neo_6m_get_lattitude - Function returns float
  • gps_neo_6m_get_lattitude_direction - Function returns byte
  • gps_neo_6m_get_longtitude - Function returns float
  • gps_neo_6m_get_longtitude_direction - Function returns byte
  • gps_neo_6m_get_nr_of_statellites - Function returns byte
  • gps_neo_6m_get_time - Procedure
  • gps_neo_6m_init - Procedure
  • gps_neo_6m_status_active - Function returns bit


gps_neo_6m_data_available - JALlib Procedures Help

gps_neo_6m_data_available JALLIB FUNCTION

Signature

function gps_neo_6m_data_available() return bit is

Description

Return TRUE if data is available. This call will reset this flag.
Initially this will be time and date data.
For GPS presence of location data check gps_neo_6m_status_active().

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_gps_neo_6m_ssd1306_clock.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M receiver showing a clock on the SSD1306
-- Author: Rob Jansen, Copyright (c) 2021..2025 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the feature of the GPS NEO-6M library showting the time
--              and date using the SSD1306 for the display.
--
-- Sources:
--
-- Notes: The GPS NEO 6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the main program.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Define the pins for the SSD1306. In this case we define only the IIC
const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
const bit _i2c_level = TRUE   -- i2c levels (not SMB)
alias i2c_scl is pin_C0
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1
alias i2c_sda_direction is pin_C1_direction
include i2c_hardware
i2c_initialize()

-- Since this PIC does not have more than 1024 bytes of data memory we use
-- will write the text only mode.
const SSD1306_TEXT_ONLY = TRUE

-- Font library.
include glcd_6x8_font
include glcd_font
glcd_font_use(FONT_6X8)

-- Include and initialize the GLCD lib. This will also initialize the IIC
-- interface.
include glcd_ssd1306
ssd1306_init()

-- Variables.
var byte hours, minutes, seconds
var byte date, month, year

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Main program starts here.

-- Write some text.
ssd1306_clear_screen()
glcd_font_use(FONT_6X8)
ssd1306_goto(10,0)
print_string(glcd,"JAL GPS NEO-6M library SSD1306 Clock Demo")

forever loop

   -- Get the data and display it.
   if gps_neo_6m_data_available() then

      ssd1306_goto(10,3)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(hours))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(minutes))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(seconds))

      ssd1306_goto(10,4)
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(date))
      print_string(glcd, "-")
      print_byte_dec(glcd, bcd2bin(month))
      print_string(glcd, "-")
      print_word_dec(glcd, word(bcd2bin(year))+2000)
   else
      -- No data yet.
      ssd1306_goto(10,3)
      print_string(glcd, "00:00:00")
      ssd1306_goto(10,4)
      print_string(glcd, "00-00-0000")
   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_date - JALlib Procedures Help

gps_neo_6m_get_date JALLIB PROCEDURE

Signature

procedure gps_neo_6m_get_date(byte out date, byte out month,

Description

Return received GPS date. Date is returned in BCD format.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_gps_neo_6m_ssd1306_clock.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M receiver showing a clock on the SSD1306
-- Author: Rob Jansen, Copyright (c) 2021..2025 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the feature of the GPS NEO-6M library showting the time
--              and date using the SSD1306 for the display.
--
-- Sources:
--
-- Notes: The GPS NEO 6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the main program.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Define the pins for the SSD1306. In this case we define only the IIC
const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
const bit _i2c_level = TRUE   -- i2c levels (not SMB)
alias i2c_scl is pin_C0
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1
alias i2c_sda_direction is pin_C1_direction
include i2c_hardware
i2c_initialize()

-- Since this PIC does not have more than 1024 bytes of data memory we use
-- will write the text only mode.
const SSD1306_TEXT_ONLY = TRUE

-- Font library.
include glcd_6x8_font
include glcd_font
glcd_font_use(FONT_6X8)

-- Include and initialize the GLCD lib. This will also initialize the IIC
-- interface.
include glcd_ssd1306
ssd1306_init()

-- Variables.
var byte hours, minutes, seconds
var byte date, month, year

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Main program starts here.

-- Write some text.
ssd1306_clear_screen()
glcd_font_use(FONT_6X8)
ssd1306_goto(10,0)
print_string(glcd,"JAL GPS NEO-6M library SSD1306 Clock Demo")

forever loop

   -- Get the data and display it.
   if gps_neo_6m_data_available() then

      ssd1306_goto(10,3)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(hours))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(minutes))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(seconds))

      ssd1306_goto(10,4)
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(date))
      print_string(glcd, "-")
      print_byte_dec(glcd, bcd2bin(month))
      print_string(glcd, "-")
      print_word_dec(glcd, word(bcd2bin(year))+2000)
   else
      -- No data yet.
      ssd1306_goto(10,3)
      print_string(glcd, "00:00:00")
      ssd1306_goto(10,4)
      print_string(glcd, "00-00-0000")
   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_lattitude - JALlib Procedures Help

gps_neo_6m_get_lattitude JALLIB FUNCTION

Signature

function gps_neo_6m_get_lattitude() return float is

Description

Return the received GPS lattitude coordinates. Only valid when
gps_neo_6m_status_active() returns TRUE.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

float - Function return value

Example

From sample file: 16f1825_gps_neo_6m_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M library.
-- Author: Rob Jansen, Copyright (c) 2021..2023 all rights reserved.
-- Adapted-by:
-- Revision: $Revision$
--
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the GPS NEO-6M library printing
--              the GPS time, GPS date and GPS location using the serial interface.
--
-- Sources:
--
-- Notes: The GPS NEO-6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the
--        main program before including the GPS NEO-6M library.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
alias serial_data is serial_hw_data
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Variables --
var byte hours, minutes, seconds
var byte date, month, year
var byte index

-- Local procedures --

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial_data = "0"
   end if
   print_byte_dec(serial_data, value)
end procedure

-- Print the given float value with the given precision.
procedure print_float_value(float in value, byte in precision) is

   var dword no_float_value

   no_float_value = dword(value)
   print_dword_dec(serial_data, no_float_value)
   serial_data = "."
   -- Print the faction
   for precision loop
     value = value * 10.0
     no_float_value = dword(value) % 10
     serial_data = byte(no_float_value) + "0"
   end loop

end procedure

-- The main program starts here --
print_crlf(serial_data)
print_string(serial_data, "GPS NEO 6M sample program showing, the GPS Time, Date and GPS Coordinates.\r\n")

forever loop

   if gps_neo_6m_data_available() then

      -- Print the time.
      print_crlf(serial_data)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS time in UTC + 1 is (hours:minutes:seconds): ")
      -- Make the hours UTC + 1, wrap when GPS time is 23.
      print_decimal((bcd2bin(hours) + 1) % 24)
      print_string(serial_data, ":")
      print_decimal(bcd2bin(minutes))
      print_string(serial_data, ":")
      print_decimal(bcd2bin(seconds))
      print_crlf(serial_data)

      -- Print the date.
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS date is (date-month-year): ")
      print_decimal(bcd2bin(date))
      print_string(serial_data, "-")
      print_decimal(bcd2bin(month))
      print_string(serial_data, "-")
      -- Add the century to the year.
      print_word_dec(serial_data, word(bcd2bin(year)) + 2000)
      print_crlf(serial_data)

      -- Check if GPS data is available (GPS status is active).
      if gps_neo_6m_status_active() then
         print_string(serial_data, "GPS location data is available.\r\n")

         print_string(serial_data, "GPS lattitude: ")
         print_float_value(gps_neo_6m_get_lattitude(), 5)
         serial_data = ","
         serial_data = gps_neo_6m_get_lattitude_direction()
         print_crlf(serial_data)

         print_string(serial_data, "GPS longtitude: ")
         print_float_value(gps_neo_6m_get_longtitude(),5)
         serial_data = ","
         serial_data = gps_neo_6m_get_longtitude_direction()
         print_crlf(serial_data)
      else
         print_string(serial_data, "GPS location data is not available.\r\n")
      end if

      -- Print the number of satellites that we see.
      print_string(serial_data, "Number of satellites: ")
      print_byte_dec(serial_data, gps_neo_6m_get_nr_of_statellites())
      print_crlf(serial_data)

   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_lattitude_direction - JALlib Procedures Help

gps_neo_6m_get_lattitude_direction JALLIB FUNCTION

Signature

function gps_neo_6m_get_lattitude_direction() return byte is

Description

Return the received GPS lattitude direction. Only valid when
gps_neo_6m_status_active() returns TRUE.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_gps_neo_6m_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M library.
-- Author: Rob Jansen, Copyright (c) 2021..2023 all rights reserved.
-- Adapted-by:
-- Revision: $Revision$
--
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the GPS NEO-6M library printing
--              the GPS time, GPS date and GPS location using the serial interface.
--
-- Sources:
--
-- Notes: The GPS NEO-6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the
--        main program before including the GPS NEO-6M library.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
alias serial_data is serial_hw_data
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Variables --
var byte hours, minutes, seconds
var byte date, month, year
var byte index

-- Local procedures --

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial_data = "0"
   end if
   print_byte_dec(serial_data, value)
end procedure

-- Print the given float value with the given precision.
procedure print_float_value(float in value, byte in precision) is

   var dword no_float_value

   no_float_value = dword(value)
   print_dword_dec(serial_data, no_float_value)
   serial_data = "."
   -- Print the faction
   for precision loop
     value = value * 10.0
     no_float_value = dword(value) % 10
     serial_data = byte(no_float_value) + "0"
   end loop

end procedure

-- The main program starts here --
print_crlf(serial_data)
print_string(serial_data, "GPS NEO 6M sample program showing, the GPS Time, Date and GPS Coordinates.\r\n")

forever loop

   if gps_neo_6m_data_available() then

      -- Print the time.
      print_crlf(serial_data)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS time in UTC + 1 is (hours:minutes:seconds): ")
      -- Make the hours UTC + 1, wrap when GPS time is 23.
      print_decimal((bcd2bin(hours) + 1) % 24)
      print_string(serial_data, ":")
      print_decimal(bcd2bin(minutes))
      print_string(serial_data, ":")
      print_decimal(bcd2bin(seconds))
      print_crlf(serial_data)

      -- Print the date.
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS date is (date-month-year): ")
      print_decimal(bcd2bin(date))
      print_string(serial_data, "-")
      print_decimal(bcd2bin(month))
      print_string(serial_data, "-")
      -- Add the century to the year.
      print_word_dec(serial_data, word(bcd2bin(year)) + 2000)
      print_crlf(serial_data)

      -- Check if GPS data is available (GPS status is active).
      if gps_neo_6m_status_active() then
         print_string(serial_data, "GPS location data is available.\r\n")

         print_string(serial_data, "GPS lattitude: ")
         print_float_value(gps_neo_6m_get_lattitude(), 5)
         serial_data = ","
         serial_data = gps_neo_6m_get_lattitude_direction()
         print_crlf(serial_data)

         print_string(serial_data, "GPS longtitude: ")
         print_float_value(gps_neo_6m_get_longtitude(),5)
         serial_data = ","
         serial_data = gps_neo_6m_get_longtitude_direction()
         print_crlf(serial_data)
      else
         print_string(serial_data, "GPS location data is not available.\r\n")
      end if

      -- Print the number of satellites that we see.
      print_string(serial_data, "Number of satellites: ")
      print_byte_dec(serial_data, gps_neo_6m_get_nr_of_statellites())
      print_crlf(serial_data)

   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_longtitude - JALlib Procedures Help

gps_neo_6m_get_longtitude JALLIB FUNCTION

Signature

function gps_neo_6m_get_longtitude() return float is

Description

Return the received GPS longtitude coordinates. Only valid when
gps_neo_6m_status_active() returns TRUE.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

float - Function return value

Example

From sample file: 16f1825_gps_neo_6m_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M library.
-- Author: Rob Jansen, Copyright (c) 2021..2023 all rights reserved.
-- Adapted-by:
-- Revision: $Revision$
--
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the GPS NEO-6M library printing
--              the GPS time, GPS date and GPS location using the serial interface.
--
-- Sources:
--
-- Notes: The GPS NEO-6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the
--        main program before including the GPS NEO-6M library.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
alias serial_data is serial_hw_data
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Variables --
var byte hours, minutes, seconds
var byte date, month, year
var byte index

-- Local procedures --

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial_data = "0"
   end if
   print_byte_dec(serial_data, value)
end procedure

-- Print the given float value with the given precision.
procedure print_float_value(float in value, byte in precision) is

   var dword no_float_value

   no_float_value = dword(value)
   print_dword_dec(serial_data, no_float_value)
   serial_data = "."
   -- Print the faction
   for precision loop
     value = value * 10.0
     no_float_value = dword(value) % 10
     serial_data = byte(no_float_value) + "0"
   end loop

end procedure

-- The main program starts here --
print_crlf(serial_data)
print_string(serial_data, "GPS NEO 6M sample program showing, the GPS Time, Date and GPS Coordinates.\r\n")

forever loop

   if gps_neo_6m_data_available() then

      -- Print the time.
      print_crlf(serial_data)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS time in UTC + 1 is (hours:minutes:seconds): ")
      -- Make the hours UTC + 1, wrap when GPS time is 23.
      print_decimal((bcd2bin(hours) + 1) % 24)
      print_string(serial_data, ":")
      print_decimal(bcd2bin(minutes))
      print_string(serial_data, ":")
      print_decimal(bcd2bin(seconds))
      print_crlf(serial_data)

      -- Print the date.
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS date is (date-month-year): ")
      print_decimal(bcd2bin(date))
      print_string(serial_data, "-")
      print_decimal(bcd2bin(month))
      print_string(serial_data, "-")
      -- Add the century to the year.
      print_word_dec(serial_data, word(bcd2bin(year)) + 2000)
      print_crlf(serial_data)

      -- Check if GPS data is available (GPS status is active).
      if gps_neo_6m_status_active() then
         print_string(serial_data, "GPS location data is available.\r\n")

         print_string(serial_data, "GPS lattitude: ")
         print_float_value(gps_neo_6m_get_lattitude(), 5)
         serial_data = ","
         serial_data = gps_neo_6m_get_lattitude_direction()
         print_crlf(serial_data)

         print_string(serial_data, "GPS longtitude: ")
         print_float_value(gps_neo_6m_get_longtitude(),5)
         serial_data = ","
         serial_data = gps_neo_6m_get_longtitude_direction()
         print_crlf(serial_data)
      else
         print_string(serial_data, "GPS location data is not available.\r\n")
      end if

      -- Print the number of satellites that we see.
      print_string(serial_data, "Number of satellites: ")
      print_byte_dec(serial_data, gps_neo_6m_get_nr_of_statellites())
      print_crlf(serial_data)

   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_longtitude_direction - JALlib Procedures Help

gps_neo_6m_get_longtitude_direction JALLIB FUNCTION

Signature

function gps_neo_6m_get_longtitude_direction() return byte is

Description

Return the received GPS longtitude direction. Only valid when
gps_neo_6m_status_active() returns TRUE.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_gps_neo_6m_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M library.
-- Author: Rob Jansen, Copyright (c) 2021..2023 all rights reserved.
-- Adapted-by:
-- Revision: $Revision$
--
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the GPS NEO-6M library printing
--              the GPS time, GPS date and GPS location using the serial interface.
--
-- Sources:
--
-- Notes: The GPS NEO-6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the
--        main program before including the GPS NEO-6M library.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
alias serial_data is serial_hw_data
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Variables --
var byte hours, minutes, seconds
var byte date, month, year
var byte index

-- Local procedures --

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial_data = "0"
   end if
   print_byte_dec(serial_data, value)
end procedure

-- Print the given float value with the given precision.
procedure print_float_value(float in value, byte in precision) is

   var dword no_float_value

   no_float_value = dword(value)
   print_dword_dec(serial_data, no_float_value)
   serial_data = "."
   -- Print the faction
   for precision loop
     value = value * 10.0
     no_float_value = dword(value) % 10
     serial_data = byte(no_float_value) + "0"
   end loop

end procedure

-- The main program starts here --
print_crlf(serial_data)
print_string(serial_data, "GPS NEO 6M sample program showing, the GPS Time, Date and GPS Coordinates.\r\n")

forever loop

   if gps_neo_6m_data_available() then

      -- Print the time.
      print_crlf(serial_data)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS time in UTC + 1 is (hours:minutes:seconds): ")
      -- Make the hours UTC + 1, wrap when GPS time is 23.
      print_decimal((bcd2bin(hours) + 1) % 24)
      print_string(serial_data, ":")
      print_decimal(bcd2bin(minutes))
      print_string(serial_data, ":")
      print_decimal(bcd2bin(seconds))
      print_crlf(serial_data)

      -- Print the date.
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS date is (date-month-year): ")
      print_decimal(bcd2bin(date))
      print_string(serial_data, "-")
      print_decimal(bcd2bin(month))
      print_string(serial_data, "-")
      -- Add the century to the year.
      print_word_dec(serial_data, word(bcd2bin(year)) + 2000)
      print_crlf(serial_data)

      -- Check if GPS data is available (GPS status is active).
      if gps_neo_6m_status_active() then
         print_string(serial_data, "GPS location data is available.\r\n")

         print_string(serial_data, "GPS lattitude: ")
         print_float_value(gps_neo_6m_get_lattitude(), 5)
         serial_data = ","
         serial_data = gps_neo_6m_get_lattitude_direction()
         print_crlf(serial_data)

         print_string(serial_data, "GPS longtitude: ")
         print_float_value(gps_neo_6m_get_longtitude(),5)
         serial_data = ","
         serial_data = gps_neo_6m_get_longtitude_direction()
         print_crlf(serial_data)
      else
         print_string(serial_data, "GPS location data is not available.\r\n")
      end if

      -- Print the number of satellites that we see.
      print_string(serial_data, "Number of satellites: ")
      print_byte_dec(serial_data, gps_neo_6m_get_nr_of_statellites())
      print_crlf(serial_data)

   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_nr_of_statellites - JALlib Procedures Help

gps_neo_6m_get_nr_of_statellites JALLIB FUNCTION

Signature

function gps_neo_6m_get_nr_of_statellites() return byte is

Description

Return the number of satellites. Only valid when
gps_neo_6m_status_active() returns TRUE.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_gps_neo_6m_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M library.
-- Author: Rob Jansen, Copyright (c) 2021..2023 all rights reserved.
-- Adapted-by:
-- Revision: $Revision$
--
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the GPS NEO-6M library printing
--              the GPS time, GPS date and GPS location using the serial interface.
--
-- Sources:
--
-- Notes: The GPS NEO-6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the
--        main program before including the GPS NEO-6M library.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
alias serial_data is serial_hw_data
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Variables --
var byte hours, minutes, seconds
var byte date, month, year
var byte index

-- Local procedures --

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial_data = "0"
   end if
   print_byte_dec(serial_data, value)
end procedure

-- Print the given float value with the given precision.
procedure print_float_value(float in value, byte in precision) is

   var dword no_float_value

   no_float_value = dword(value)
   print_dword_dec(serial_data, no_float_value)
   serial_data = "."
   -- Print the faction
   for precision loop
     value = value * 10.0
     no_float_value = dword(value) % 10
     serial_data = byte(no_float_value) + "0"
   end loop

end procedure

-- The main program starts here --
print_crlf(serial_data)
print_string(serial_data, "GPS NEO 6M sample program showing, the GPS Time, Date and GPS Coordinates.\r\n")

forever loop

   if gps_neo_6m_data_available() then

      -- Print the time.
      print_crlf(serial_data)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS time in UTC + 1 is (hours:minutes:seconds): ")
      -- Make the hours UTC + 1, wrap when GPS time is 23.
      print_decimal((bcd2bin(hours) + 1) % 24)
      print_string(serial_data, ":")
      print_decimal(bcd2bin(minutes))
      print_string(serial_data, ":")
      print_decimal(bcd2bin(seconds))
      print_crlf(serial_data)

      -- Print the date.
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS date is (date-month-year): ")
      print_decimal(bcd2bin(date))
      print_string(serial_data, "-")
      print_decimal(bcd2bin(month))
      print_string(serial_data, "-")
      -- Add the century to the year.
      print_word_dec(serial_data, word(bcd2bin(year)) + 2000)
      print_crlf(serial_data)

      -- Check if GPS data is available (GPS status is active).
      if gps_neo_6m_status_active() then
         print_string(serial_data, "GPS location data is available.\r\n")

         print_string(serial_data, "GPS lattitude: ")
         print_float_value(gps_neo_6m_get_lattitude(), 5)
         serial_data = ","
         serial_data = gps_neo_6m_get_lattitude_direction()
         print_crlf(serial_data)

         print_string(serial_data, "GPS longtitude: ")
         print_float_value(gps_neo_6m_get_longtitude(),5)
         serial_data = ","
         serial_data = gps_neo_6m_get_longtitude_direction()
         print_crlf(serial_data)
      else
         print_string(serial_data, "GPS location data is not available.\r\n")
      end if

      -- Print the number of satellites that we see.
      print_string(serial_data, "Number of satellites: ")
      print_byte_dec(serial_data, gps_neo_6m_get_nr_of_statellites())
      print_crlf(serial_data)

   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_get_time - JALlib Procedures Help

gps_neo_6m_get_time JALLIB PROCEDURE

Signature

procedure gps_neo_6m_get_time(byte out hours, byte out minutes,

Description

Return received GPS time. Time is returned in BCD format.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_gps_neo_6m_ssd1306_clock.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M receiver showing a clock on the SSD1306
-- Author: Rob Jansen, Copyright (c) 2021..2025 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the feature of the GPS NEO-6M library showting the time
--              and date using the SSD1306 for the display.
--
-- Sources:
--
-- Notes: The GPS NEO 6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the main program.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Define the pins for the SSD1306. In this case we define only the IIC
const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
const bit _i2c_level = TRUE   -- i2c levels (not SMB)
alias i2c_scl is pin_C0
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1
alias i2c_sda_direction is pin_C1_direction
include i2c_hardware
i2c_initialize()

-- Since this PIC does not have more than 1024 bytes of data memory we use
-- will write the text only mode.
const SSD1306_TEXT_ONLY = TRUE

-- Font library.
include glcd_6x8_font
include glcd_font
glcd_font_use(FONT_6X8)

-- Include and initialize the GLCD lib. This will also initialize the IIC
-- interface.
include glcd_ssd1306
ssd1306_init()

-- Variables.
var byte hours, minutes, seconds
var byte date, month, year

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Main program starts here.

-- Write some text.
ssd1306_clear_screen()
glcd_font_use(FONT_6X8)
ssd1306_goto(10,0)
print_string(glcd,"JAL GPS NEO-6M library SSD1306 Clock Demo")

forever loop

   -- Get the data and display it.
   if gps_neo_6m_data_available() then

      ssd1306_goto(10,3)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(hours))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(minutes))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(seconds))

      ssd1306_goto(10,4)
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(date))
      print_string(glcd, "-")
      print_byte_dec(glcd, bcd2bin(month))
      print_string(glcd, "-")
      print_word_dec(glcd, word(bcd2bin(year))+2000)
   else
      -- No data yet.
      ssd1306_goto(10,3)
      print_string(glcd, "00:00:00")
      ssd1306_goto(10,4)
      print_string(glcd, "00-00-0000")
   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_init - JALlib Procedures Help

gps_neo_6m_init JALLIB PROCEDURE

Signature

procedure gps_neo_6m_init() is

Description

Initialize the GPS NEO 6M library. The peripheral interrupt and global
interrupt are enabled.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_gps_neo_6m_ssd1306_clock.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M receiver showing a clock on the SSD1306
-- Author: Rob Jansen, Copyright (c) 2021..2025 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the feature of the GPS NEO-6M library showting the time
--              and date using the SSD1306 for the display.
--
-- Sources:
--
-- Notes: The GPS NEO 6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the main program.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Define the pins for the SSD1306. In this case we define only the IIC
const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
const bit _i2c_level = TRUE   -- i2c levels (not SMB)
alias i2c_scl is pin_C0
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1
alias i2c_sda_direction is pin_C1_direction
include i2c_hardware
i2c_initialize()

-- Since this PIC does not have more than 1024 bytes of data memory we use
-- will write the text only mode.
const SSD1306_TEXT_ONLY = TRUE

-- Font library.
include glcd_6x8_font
include glcd_font
glcd_font_use(FONT_6X8)

-- Include and initialize the GLCD lib. This will also initialize the IIC
-- interface.
include glcd_ssd1306
ssd1306_init()

-- Variables.
var byte hours, minutes, seconds
var byte date, month, year

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Main program starts here.

-- Write some text.
ssd1306_clear_screen()
glcd_font_use(FONT_6X8)
ssd1306_goto(10,0)
print_string(glcd,"JAL GPS NEO-6M library SSD1306 Clock Demo")

forever loop

   -- Get the data and display it.
   if gps_neo_6m_data_available() then

      ssd1306_goto(10,3)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(hours))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(minutes))
      print_string(glcd, ":")
      print_byte_dec(glcd, bcd2bin(seconds))

      ssd1306_goto(10,4)
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_byte_dec(glcd, bcd2bin(date))
      print_string(glcd, "-")
      print_byte_dec(glcd, bcd2bin(month))
      print_string(glcd, "-")
      print_word_dec(glcd, word(bcd2bin(year))+2000)
   else
      -- No data yet.
      ssd1306_goto(10,3)
      print_string(glcd, "00:00:00")
      ssd1306_goto(10,4)
      print_string(glcd, "00-00-0000")
   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


gps_neo_6m_status_active - JALlib Procedures Help

gps_neo_6m_status_active JALLIB FUNCTION

Signature

function gps_neo_6m_status_active() return bit is

Description

Return TRUE if the GPS data is active, that means that GPS coordinates
are available.

Include

To use this procedure, include the library:

include gps_neo_6m

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_gps_neo_6m_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the GPS NEO-6M library.
-- Author: Rob Jansen, Copyright (c) 2021..2023 all rights reserved.
-- Adapted-by:
-- Revision: $Revision$
--
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the GPS NEO-6M library printing
--              the GPS time, GPS date and GPS location using the serial interface.
--
-- Sources:
--
-- Notes: The GPS NEO-6M receiver uses a serial interface so at least one of the
--        JAL serial hardware libraries must be included and initialized by the
--        main program before including the GPS NEO-6M library.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Before including the GPS library, select a serial interface. You can select
-- from serial_hardware or serial_hardware2, this because the library captures
-- and processes the data on an interrupt basis. Only USART reception is used
-- by the library. The main program can still use the USART for transmission.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP to TX of GPS Module
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP to Computer
const serial_hw_baudrate = 9600                -- Module uses 9600 baud.
include serial_hardware                        -- Alternative for serial_hw_int_cts
alias serial_data is serial_hw_data
serial_hw_init

-- Set-up required aliases for the GPS library.
alias gps_neo_6m_serial_data is serial_hw_data
alias GPS_NEO_6M_SERIAL_RX_INT_FLAG is PIR1_RCIF
alias GPS_NEO_6M_SERIAL_RX_INT_ENABLE is PIE1_RCIE
include gps_neo_6m
gps_neo_6m_init()
include print

-- Variables --
var byte hours, minutes, seconds
var byte date, month, year
var byte index

-- Local procedures --

-- Convert BDC to binary. Copied from rtc_common.jal
function bcd2bin(byte in bcd) return byte is
   var byte t                       -- intermediate value
   t = (bcd >> 1) & 0b0111_1000     -- tens * 8
   return (bcd - t + (t >> 2))      -- bcd - tens*8 + tens*2
end function

-- Print a decimal value always with leading zero's.
procedure print_decimal(byte in value) is
   if (value < 10) then
      serial_data = "0"
   end if
   print_byte_dec(serial_data, value)
end procedure

-- Print the given float value with the given precision.
procedure print_float_value(float in value, byte in precision) is

   var dword no_float_value

   no_float_value = dword(value)
   print_dword_dec(serial_data, no_float_value)
   serial_data = "."
   -- Print the faction
   for precision loop
     value = value * 10.0
     no_float_value = dword(value) % 10
     serial_data = byte(no_float_value) + "0"
   end loop

end procedure

-- The main program starts here --
print_crlf(serial_data)
print_string(serial_data, "GPS NEO 6M sample program showing, the GPS Time, Date and GPS Coordinates.\r\n")

forever loop

   if gps_neo_6m_data_available() then

      -- Print the time.
      print_crlf(serial_data)
      gps_neo_6m_get_time(hours, minutes, seconds)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS time in UTC + 1 is (hours:minutes:seconds): ")
      -- Make the hours UTC + 1, wrap when GPS time is 23.
      print_decimal((bcd2bin(hours) + 1) % 24)
      print_string(serial_data, ":")
      print_decimal(bcd2bin(minutes))
      print_string(serial_data, ":")
      print_decimal(bcd2bin(seconds))
      print_crlf(serial_data)

      -- Print the date.
      gps_neo_6m_get_date(date, month, year)
      -- Data is BCD, convert to binary before printing.
      print_string(serial_data, "GPS date is (date-month-year): ")
      print_decimal(bcd2bin(date))
      print_string(serial_data, "-")
      print_decimal(bcd2bin(month))
      print_string(serial_data, "-")
      -- Add the century to the year.
      print_word_dec(serial_data, word(bcd2bin(year)) + 2000)
      print_crlf(serial_data)

      -- Check if GPS data is available (GPS status is active).
      if gps_neo_6m_status_active() then
         print_string(serial_data, "GPS location data is available.\r\n")

         print_string(serial_data, "GPS lattitude: ")
         print_float_value(gps_neo_6m_get_lattitude(), 5)
         serial_data = ","
         serial_data = gps_neo_6m_get_lattitude_direction()
         print_crlf(serial_data)

         print_string(serial_data, "GPS longtitude: ")
         print_float_value(gps_neo_6m_get_longtitude(),5)
         serial_data = ","
         serial_data = gps_neo_6m_get_longtitude_direction()
         print_crlf(serial_data)
      else
         print_string(serial_data, "GPS location data is not available.\r\n")
      end if

      -- Print the number of satellites that we see.
      print_string(serial_data, "Number of satellites: ")
      print_byte_dec(serial_data, gps_neo_6m_get_nr_of_statellites())
      print_crlf(serial_data)

   end if

end loop

Generated by JALlib CHM Help System | Source: gps_neo_6m.jal


hcsr04.jal - JALLIB Library Documentation

hcsr04.jal JALLIB LIBRARY

Title

HC-SR04 Ultrasonic Ranging Module Library.

Author

Rob Jansen, Copyright (c) 2023..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for the HC-SR04 Ultrasonic Ranging Module.
The library can be configured to use either the external
interrupt or an IOC interrupt to measure the echo signal
from the module using Timer 1.
The default is using an external interrupt. In order to switch
to using an IOC interrupt the user must initialize the IOC
to be active on both the rising and falling edge and must
define the following alias (example for IOC on pin A2):
-) alias hcsr04_ioc_flag is IOCAF_IOCAF2
The library uses Timer 1 to measure echo signal.
The user must initialize Timer 1. Bit times are based on 1 us.
If Timer 1 does not run at 1 MHz then the user has to define
the dword constant HCSR04_SCALING, where a value of 100 equals
Timer 1 running at 1 MHz (default so not required to define).
When Timer 1 runs at 1.25 MHz the dword constant HCSR04_SCALING
must equal 125. When Timer 1 runs at 0.75 MHz then
HCSR04_SCALING must equal 75. Timer 1 must not run a frequency
higher than 2 MHz to prevent overflow. It is better to stay
as close as possiblt to a Timer 1 clock of 1 MHz.

Notes

The echo signal ranges from about 150 us to 25 ms. In case
there is no object, the echo signal is about 38 ms. If
no echo signal is received, the library will timeout after
65 ms when Timer 1 runs at 1 MHz.

Sources

Datasheet Ultrasonic ranging module : HC-SR04.

----------------------------------------------------------------------------
-------------------------- Public API --------------------------------------
----------------------------------------------------------------------------

----------------------------------------------------------------------------
Initialize the HCSR04 library. This will will enable the required interrupts.
----------------------------------------------------------------------------

Constants and Variables

HCSR04_SCALING - const dword = 100

Routines

  • _hcsr04_get_timer1_value - Function returns word
  • _hcsr04_handle_interrupt_flag - Function returns bit
  • _hcsr04_interrupt - Procedure
  • _hcsr04_timer1_interrupt - Procedure
  • _hcsr04_timer1_reset - Procedure
  • hcsr04_get_distance_mil - Function returns dword
  • hcsr04_get_distance_mm - Function returns word
  • hcsr04_init - Procedure
  • hcsr04_measurement_done - Function returns bit
  • hcsr04_measurement_error - Function returns bit
  • hcsr04_start_measurement - Procedure


hcsr04_get_distance_mil - JALlib Procedures Help

hcsr04_get_distance_mil JALLIB FUNCTION

Signature

function hcsr04_get_distance_mil() return dword is

Description

Returns the last measured distance in mil.

Include

To use this procedure, include the library:

include hcsr04

Parameters

None

Return Value

None

Example

From sample file: 16f1825_hcsr04_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the HC-SR04 Ultrasonic Ranging Module.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the HC-SR04
--              Ultra Sonic Ranging Module.
--              The serial interface is used to display the measured distance.
--              The HC-SR04 library uses timer 1 to measure the distance.
--              Since a clock of 20 MHz is used we need scaling for the library
--              to measure the distance correctly.
--
include 16f1825

-- This program uses a crystal of 20 MHz.
pragma target clock    20_000_000      -- Oscillator frequency
pragma target OSC      HS              -- Crystal or resonator
pragma target PLLEN    DISABLED        -- No PLL
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- Int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
OSCCON_SCS = 0b00                      -- Select primary oscillator

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Set up the serial interface.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print

-- Settings for the HCSR04 Ultrasonic Ranging Motule. The library uses timer 1
-- which is assumed to run at 1 MHz. We use Fosc/4 and a prescaler of 1:4.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 5 MHz.
T1CON_T1CKPS = 0b10 -- Prescaler 1:4, gives 1.25 MHz.
-- We then get a timer 1 running at 1.25 MHz so we need scaling.
const dword HCSR04_SCALING = 125

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the HCSR04 library will use the external interrupt (default), otherwise
-- it wil use the IOC interrupt.
-- const IOC_VERSION = TRUE -- When commented out using the IOC interrupt.
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A0 in this example.
   IOCAP_IOCAP0 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN0 = TRUE -- Set ioc interrupt on negative edge.
   alias hcsr04_ioc_flag is IOCAF_IOCAF0
   -- Interrupt using IOC.
   alias hcsr04_echo_pin_direction is pin_a0_direction -- Pin 13 for 14 pin DIP
else
   -- Interrupt using INT.
   alias hcsr04_echo_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Control pin for the module to start an echo.
alias hcsr04_trigger_pin is pin_c2 -- Pin 8 for 14 pin DIP
alias hcsr04_trigger_pin_direction is pin_c2_direction

-- Now we can include the library.
include hcsr04
hcsr04_init()

-- Variables.
var dword distance
var bit measurement_busy

print_string(serial, "Sample program for the HC-SR04.\r\n\r\n")
measurement_busy = FALSE

forever  loop

   -- Start a measurement and wait for the result.
   if !measurement_busy then
      hcsr04_start_measurement()
      measurement_busy= TRUE
   end if

   if hcsr04_measurement_done() then
      -- Print distance in mm and mil.
      print_string(serial, "Distance measured is: ")
      print_word_dec(serial, hcsr04_get_distance_mm())
      print_string(serial, " mm or ")
      print_dword_dec(serial, hcsr04_get_distance_mil())
      print_string(serial, " mil.\r\n")

      -- Print distance in cm and inch.
      print_string(serial, "Distance measured is: ")
      print_word_dec(serial, hcsr04_get_distance_mm() / 10)
      serial = "."
      serial = byte(hcsr04_get_distance_mm() % 10) + "0"
      print_string(serial, " cm or ")
      -- We need to do more to get the decimal.
      distance = hcsr04_get_distance_mil() / 1_000
      print_word_dec(serial, word(distance))
      serial = "."
      distance = hcsr04_get_distance_mil() - (distance * 1_000)
      print_byte_dec(serial, byte(distance / 100))
      print_string(serial, " inch.\r\n\r\n")

      measurement_busy = FALSE
   elsif hcsr04_measurement_error() then
      print_string(serial, "Error measuring the distance.\r\n\r\n")
      measurement_busy = FALSE
   end if

   _usec_delay(500_000)

end loop

Generated by JALlib CHM Help System | Source: hcsr04.jal


hcsr04_get_distance_mm - JALlib Procedures Help

hcsr04_get_distance_mm JALLIB FUNCTION

Signature

function hcsr04_get_distance_mm() return word is

Description

Returns the last measured distance in milimeter.

Include

To use this procedure, include the library:

include hcsr04

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_hcsr04_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the HC-SR04 Ultrasonic Ranging Module
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the HC-SR04
--              Ultra Sonic Ranging Module.
--              The LED bar is used to show the distance measured. The closed
--              to the module the more LEDs will be turned on.
--              The HC-SR04 library uses timer 1 to measure the distance.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Settings for the HCSR04 Ultrasonic Ranging Motule. The library uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a 1 MHz clock cannot be obtained the user must use HCSR04_SCALING.
--       For more information see the hcsr04 library.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the HCSR04 library will use the external interrupt (default), otherwise
-- it wil use the IOC interrupt.
-- const IOC_VERSION = TRUE -- When commented out using the IOC interrupt.
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias hcsr04_ioc_flag is IOCAF_IOCAF5
   -- Interrupt using IOC.
   alias hcsr04_echo_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interrupt using INT.
   alias hcsr04_echo_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Control pin for the module to start an echo.
alias hcsr04_trigger_pin is pin_a4 -- Pin 3 for 14 pin DIP
alias hcsr04_trigger_pin_direction is pin_a4_direction

-- Now we can include the library.
include hcsr04
hcsr04_init

-- Define the LED bar, we use port C (C0 .. C5).
alias led_bar is portc
portc_direction = OUTPUT

-- Some distance constants in mm
const dword MIN_DISTANCE = 20    -- 2 cm
const dword MAX_DISTANCE = 4_000 -- 400 cm
-- We have 6 LEDs and we only indicate a distance up to 30 cm
-- so 5 cm of 50 mm per LED.
const word MM_PER_LED = 50

-- Variables.
var word distance
var bit measurement_busy

measurement_busy = FALSE
led_bar = 0b0011_1111
_usec_delay(1_000_000)
led_bar = 0x00

forever  loop

   -- Start a measurement and wait for the result.
   if !measurement_busy then
      hcsr04_start_measurement()
      measurement_busy= TRUE
   end if

   if hcsr04_measurement_done() then
      --Get distance in in mm.
      distance = word(hcsr04_get_distance_mm() - MIN_DISTANCE)

      -- Create a LED bar based on the distance. The shorter the
      -- distance the more LEDs will be turned on.
      if (distance > (6 * MM_PER_LED)) then
         led_bar = 0b0011_1111
      elsif (distance > (5 * MM_PER_LED)) then
         led_bar = 0b0001_1111
      elsif (distance > (4 * MM_PER_LED)) then
         led_bar = 0b0000_1111
      elsif (distance > (3 * MM_PER_LED)) then
         led_bar = 0b0000_0111
      elsif (distance > (2 * MM_PER_LED)) then
         led_bar = 0b0000_0011
      elsif (distance > MM_PER_LED) then
         led_bar = 0b0000_0001
      else
         led_bar = 0b0000_0000
      end if
      measurement_busy = FALSE
   elsif hcsr04_measurement_error() then
      -- Blink the whole LED bar.
      for 5 loop
         led_bar = 0b0011_1111
         _usec_delay(500_000)
         led_bar = OFF
         _usec_delay(500_000)
      end loop
      measurement_busy = FALSE
   end if

   _usec_delay(100_000)

end loop

Generated by JALlib CHM Help System | Source: hcsr04.jal


hcsr04_init - JALlib Procedures Help

hcsr04_init JALLIB PROCEDURE

Signature

procedure hcsr04_init() is

Description

Initialize the HCSR04 library. This will enable the required interrupts.

Include

To use this procedure, include the library:

include hcsr04

Parameters

None

Return Value

None

Example

From sample file: 16f1825_hcsr04_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the HC-SR04 Ultrasonic Ranging Module
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the HC-SR04
--              Ultra Sonic Ranging Module.
--              The LED bar is used to show the distance measured. The closed
--              to the module the more LEDs will be turned on.
--              The HC-SR04 library uses timer 1 to measure the distance.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Settings for the HCSR04 Ultrasonic Ranging Motule. The library uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a 1 MHz clock cannot be obtained the user must use HCSR04_SCALING.
--       For more information see the hcsr04 library.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the HCSR04 library will use the external interrupt (default), otherwise
-- it wil use the IOC interrupt.
-- const IOC_VERSION = TRUE -- When commented out using the IOC interrupt.
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias hcsr04_ioc_flag is IOCAF_IOCAF5
   -- Interrupt using IOC.
   alias hcsr04_echo_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interrupt using INT.
   alias hcsr04_echo_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Control pin for the module to start an echo.
alias hcsr04_trigger_pin is pin_a4 -- Pin 3 for 14 pin DIP
alias hcsr04_trigger_pin_direction is pin_a4_direction

-- Now we can include the library.
include hcsr04
hcsr04_init

-- Define the LED bar, we use port C (C0 .. C5).
alias led_bar is portc
portc_direction = OUTPUT

-- Some distance constants in mm
const dword MIN_DISTANCE = 20    -- 2 cm
const dword MAX_DISTANCE = 4_000 -- 400 cm
-- We have 6 LEDs and we only indicate a distance up to 30 cm
-- so 5 cm of 50 mm per LED.
const word MM_PER_LED = 50

-- Variables.
var word distance
var bit measurement_busy

measurement_busy = FALSE
led_bar = 0b0011_1111
_usec_delay(1_000_000)
led_bar = 0x00

forever  loop

   -- Start a measurement and wait for the result.
   if !measurement_busy then
      hcsr04_start_measurement()
      measurement_busy= TRUE
   end if

   if hcsr04_measurement_done() then
      --Get distance in in mm.
      distance = word(hcsr04_get_distance_mm() - MIN_DISTANCE)

      -- Create a LED bar based on the distance. The shorter the
      -- distance the more LEDs will be turned on.
      if (distance > (6 * MM_PER_LED)) then
         led_bar = 0b0011_1111
      elsif (distance > (5 * MM_PER_LED)) then
         led_bar = 0b0001_1111
      elsif (distance > (4 * MM_PER_LED)) then
         led_bar = 0b0000_1111
      elsif (distance > (3 * MM_PER_LED)) then
         led_bar = 0b0000_0111
      elsif (distance > (2 * MM_PER_LED)) then
         led_bar = 0b0000_0011
      elsif (distance > MM_PER_LED) then
         led_bar = 0b0000_0001
      else
         led_bar = 0b0000_0000
      end if
      measurement_busy = FALSE
   elsif hcsr04_measurement_error() then
      -- Blink the whole LED bar.
      for 5 loop
         led_bar = 0b0011_1111
         _usec_delay(500_000)
         led_bar = OFF
         _usec_delay(500_000)
      end loop
      measurement_busy = FALSE
   end if

   _usec_delay(100_000)

end loop

Generated by JALlib CHM Help System | Source: hcsr04.jal


hcsr04_measurement_done - JALlib Procedures Help

hcsr04_measurement_done JALLIB FUNCTION

Signature

function hcsr04_measurement_done() return bit is

Description

Returns TRUE when a distance measurement was done.

Include

To use this procedure, include the library:

include hcsr04

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_hcsr04_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the HC-SR04 Ultrasonic Ranging Module
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the HC-SR04
--              Ultra Sonic Ranging Module.
--              The LED bar is used to show the distance measured. The closed
--              to the module the more LEDs will be turned on.
--              The HC-SR04 library uses timer 1 to measure the distance.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Settings for the HCSR04 Ultrasonic Ranging Motule. The library uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a 1 MHz clock cannot be obtained the user must use HCSR04_SCALING.
--       For more information see the hcsr04 library.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the HCSR04 library will use the external interrupt (default), otherwise
-- it wil use the IOC interrupt.
-- const IOC_VERSION = TRUE -- When commented out using the IOC interrupt.
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias hcsr04_ioc_flag is IOCAF_IOCAF5
   -- Interrupt using IOC.
   alias hcsr04_echo_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interrupt using INT.
   alias hcsr04_echo_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Control pin for the module to start an echo.
alias hcsr04_trigger_pin is pin_a4 -- Pin 3 for 14 pin DIP
alias hcsr04_trigger_pin_direction is pin_a4_direction

-- Now we can include the library.
include hcsr04
hcsr04_init

-- Define the LED bar, we use port C (C0 .. C5).
alias led_bar is portc
portc_direction = OUTPUT

-- Some distance constants in mm
const dword MIN_DISTANCE = 20    -- 2 cm
const dword MAX_DISTANCE = 4_000 -- 400 cm
-- We have 6 LEDs and we only indicate a distance up to 30 cm
-- so 5 cm of 50 mm per LED.
const word MM_PER_LED = 50

-- Variables.
var word distance
var bit measurement_busy

measurement_busy = FALSE
led_bar = 0b0011_1111
_usec_delay(1_000_000)
led_bar = 0x00

forever  loop

   -- Start a measurement and wait for the result.
   if !measurement_busy then
      hcsr04_start_measurement()
      measurement_busy= TRUE
   end if

   if hcsr04_measurement_done() then
      --Get distance in in mm.
      distance = word(hcsr04_get_distance_mm() - MIN_DISTANCE)

      -- Create a LED bar based on the distance. The shorter the
      -- distance the more LEDs will be turned on.
      if (distance > (6 * MM_PER_LED)) then
         led_bar = 0b0011_1111
      elsif (distance > (5 * MM_PER_LED)) then
         led_bar = 0b0001_1111
      elsif (distance > (4 * MM_PER_LED)) then
         led_bar = 0b0000_1111
      elsif (distance > (3 * MM_PER_LED)) then
         led_bar = 0b0000_0111
      elsif (distance > (2 * MM_PER_LED)) then
         led_bar = 0b0000_0011
      elsif (distance > MM_PER_LED) then
         led_bar = 0b0000_0001
      else
         led_bar = 0b0000_0000
      end if
      measurement_busy = FALSE
   elsif hcsr04_measurement_error() then
      -- Blink the whole LED bar.
      for 5 loop
         led_bar = 0b0011_1111
         _usec_delay(500_000)
         led_bar = OFF
         _usec_delay(500_000)
      end loop
      measurement_busy = FALSE
   end if

   _usec_delay(100_000)

end loop

Generated by JALlib CHM Help System | Source: hcsr04.jal


hcsr04_start_measurement - JALlib Procedures Help

hcsr04_start_measurement JALLIB PROCEDURE

Signature

procedure hcsr04_start_measurement() is

Description

Start an ultrasonic distance measurement.

Include

To use this procedure, include the library:

include hcsr04

Parameters

None

Return Value

None

Example

From sample file: 16f1825_hcsr04_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the HC-SR04 Ultrasonic Ranging Module
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows the operation of the HC-SR04
--              Ultra Sonic Ranging Module.
--              The LED bar is used to show the distance measured. The closed
--              to the module the more LEDs will be turned on.
--              The HC-SR04 library uses timer 1 to measure the distance.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Settings for the HCSR04 Ultrasonic Ranging Motule. The library uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a 1 MHz clock cannot be obtained the user must use HCSR04_SCALING.
--       For more information see the hcsr04 library.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.

-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the HCSR04 library will use the external interrupt (default), otherwise
-- it wil use the IOC interrupt.
-- const IOC_VERSION = TRUE -- When commented out using the IOC interrupt.
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias hcsr04_ioc_flag is IOCAF_IOCAF5
   -- Interrupt using IOC.
   alias hcsr04_echo_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interrupt using INT.
   alias hcsr04_echo_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Control pin for the module to start an echo.
alias hcsr04_trigger_pin is pin_a4 -- Pin 3 for 14 pin DIP
alias hcsr04_trigger_pin_direction is pin_a4_direction

-- Now we can include the library.
include hcsr04
hcsr04_init

-- Define the LED bar, we use port C (C0 .. C5).
alias led_bar is portc
portc_direction = OUTPUT

-- Some distance constants in mm
const dword MIN_DISTANCE = 20    -- 2 cm
const dword MAX_DISTANCE = 4_000 -- 400 cm
-- We have 6 LEDs and we only indicate a distance up to 30 cm
-- so 5 cm of 50 mm per LED.
const word MM_PER_LED = 50

-- Variables.
var word distance
var bit measurement_busy

measurement_busy = FALSE
led_bar = 0b0011_1111
_usec_delay(1_000_000)
led_bar = 0x00

forever  loop

   -- Start a measurement and wait for the result.
   if !measurement_busy then
      hcsr04_start_measurement()
      measurement_busy= TRUE
   end if

   if hcsr04_measurement_done() then
      --Get distance in in mm.
      distance = word(hcsr04_get_distance_mm() - MIN_DISTANCE)

      -- Create a LED bar based on the distance. The shorter the
      -- distance the more LEDs will be turned on.
      if (distance > (6 * MM_PER_LED)) then
         led_bar = 0b0011_1111
      elsif (distance > (5 * MM_PER_LED)) then
         led_bar = 0b0001_1111
      elsif (distance > (4 * MM_PER_LED)) then
         led_bar = 0b0000_1111
      elsif (distance > (3 * MM_PER_LED)) then
         led_bar = 0b0000_0111
      elsif (distance > (2 * MM_PER_LED)) then
         led_bar = 0b0000_0011
      elsif (distance > MM_PER_LED) then
         led_bar = 0b0000_0001
      else
         led_bar = 0b0000_0000
      end if
      measurement_busy = FALSE
   elsif hcsr04_measurement_error() then
      -- Blink the whole LED bar.
      for 5 loop
         led_bar = 0b0011_1111
         _usec_delay(500_000)
         led_bar = OFF
         _usec_delay(500_000)
      end loop
      measurement_busy = FALSE
   end if

   _usec_delay(100_000)

end loop

Generated by JALlib CHM Help System | Source: hcsr04.jal


hd9200_dial - JALlib Procedures Help

hd9200_dial JALLIB PROCEDURE

Signature

procedure hd9200_dial(byte in phone_numbers[], byte in length) is

Description

Send a string of numbers to output. Dial a phone number.
length is how long the sound will play in 100ms.
" " sends no sound.

Include

To use this procedure, include the library:

include dtmf_encoder_ht9200

Parameters

  • phone_numbers[] - byte in
  • length - byte in

Return Value

None

Example

From sample file: 18f4550_dtmf_encoder_ht9200.jal

-- ------------------------------------------------------
-- Title: HT9200 DTMF generator sample
--
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Select a DTMF signal to be generated by HT9200.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- Sound is only generated while chip select is LOW.
--
-- This chip is meant to use 5 bit SPI, so the CS line must be toggled for
-- each data byte sent since the SPI libraries are 8 bit.
--
-- This chip uses SPI mode 1,1 but may work with other modes.
--
include 18f4550                    -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      HS_PLL      -- HS crystal or resonator
--                                    and using PLL
pragma target PLLDIV   P5          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96)/2 -> 48 MHz
--                                    (without PLL: CPU freq. = OSC freq.)
pragma target USBDIV   P2          -- USB clock from PLL module
pragma target FCMEN    DISABLED    -- no fail-safe clock monitoring
pragma target IESO     DISABLED    -- no int/ext clock switchover
pragma target BROWNOUT DISABLED    -- no brownout detection
pragma target VREGEN   ENABLED     -- enable USB voltage regulator
--                                    (when no external regulator at Vusb)
pragma target WDT      CONTROL    -- no watchdog
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging
pragma target LVP      ENABLED     -- allow Low Voltage Programming
pragma target ICPRT    DISABLED    -- no In Circuit Debug
pragma target MCLR     EXTERNAL    -- reset externally
--
-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
--

-- delay library
include delay

-- set all IO as digital
enable_digital_io()

-- setup SPI software
alias spi_master_sw_sdi              is pin_d3
alias spi_master_sw_sdi_direction    is pin_d3_direction
alias spi_master_sw_sdo              is pin_d1
alias spi_master_sw_sdo_direction    is pin_d1_direction
alias spi_master_sw_sck              is pin_d0
alias spi_master_sw_sck_direction    is pin_d0_direction
-- define spi inputs/outputs
spi_master_sw_sdi_direction = input    -- spi input
spi_master_sw_sdo_direction = output   -- spi output
spi_master_sw_sck_direction = output   -- spi clock
--
include spi_master_sw
spi_master_sw_init(SPI_MODE_11) -- init spi, choose mode
alias spi_master is spi_master_sw
alias spi_master_set_speed is spi_master_sw_set_speed
alias spi_master_set_mode is spi_master_sw_set_mode

-- setup HT9200A
-- setup dtmf pins
alias ht9200_chip_select is pin_a1
alias ht9200_chip_select_direction is pin_a1_direction
ht9200_chip_select_direction = output
--
ht9200_chip_select = HIGH -- enable the chip
include dtmf_encoder_ht9200

-- main program
const byte phone_number[] = "555 829 9112" -- set a phone number
forever loop
   hd9200_dial(phone_number,3)
   delay_1s(1)
end loop

--

Generated by JALlib CHM Help System | Source: dtmf_encoder_ht9200.jal


http.jal - JALLIB Library Documentation

http.jal JALLIB LIBRARY

Title

HTTP - Hypertext Transfer Protocol Server BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

HTTP server for serving web pages.

Sources

http://www.faqs.org/rfcs/rfc793.html
http://www.8051projects.net/out.php?link=http://www.sics.se/~adam/uip/index.php/Main_Page
Web pages must be < 1kb. I have not tested larger http transfers.

Constants and Variables

webpage_size - var word = 0
HTTP_HEADER_OUT_SIZE - const byte = count(HTTP_HEADER) + count(HTTP_LIB_HEADER)
http_data_size - var word
http_file_size - var word

Routines

  • _size'put - Procedure
  • http_data'get - Function returns byte
  • http_data'put - Procedure
  • http_is_filename - Function returns bit
  • http_server - Procedure


http_is_filename - JALlib Procedures Help

http_is_filename JALLIB FUNCTION

Signature

function http_is_filename(byte in file_name[]) return bit is

Description

Check file name requested by client

Include

To use this procedure, include the library:

include http

Parameters

  • file_name[] - byte in

Return Value

bit - Function return value

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: http.jal


http_server - JALlib Procedures Help

http_server JALLIB PROCEDURE

Signature

procedure http_server(byte in socket, word in data_size) is

Description

No description available.

Include

To use this procedure, include the library:

include http

Parameters

  • socket - byte in
  • data_size - word in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: http.jal


humidity_sht.jal - JALLIB Library Documentation

humidity_sht.jal JALLIB LIBRARY

Title

SHTxx, for Sensirion humidity and temperature sensors

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2008

Compiler

=2.4h

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

The Sensirion SHT1x/SHT7x is a single chip relative humidity and
temperature multi sensor module comprising a calibrated digital output.
It comes in 5 flavors, with different accuracy and package style:
sensor hum acc temp acc package
SHT10 4.5% 0.5C SMD (LCC)
SHT11 3.0% 0.4C SMD (LCC)
SHT15 2.0% 0.3C SMD (LCC)
SHT71 3.0% 0.4C 4-pin single-in-line
SHT75 1.8% 0.3C 4-pin single-in-line
all consist of the same silicon: the less accurate models are sold cheaper.
My experience is mixed: I've seen some consistent +2C offset in temperature,
but good humidty measurements. The 4-pin package breaks when you touch it.
The SMD package has naked tracks underneath: you can't route under it!
If exposed to >95% RH for 10 minutes, these sensors will go beserk and need
<60% RH for an hour to recover. You might try heating them.
protocol is close to I2C, but not the same. Remember to pull up DATA.
0b0000_0011 starts temperature measurement
0b0000_0101 starts humidity measurement
device returns three bytes: MSB, LSB and CRC
this library doesn't perform any CRC check
because of self-heating, don't turn on more than 10% of the time
8/12/14 bit reading takes 20/80/320 ms
Declarations:
var bit SHT_SCK -- output pin, clock signal to sensor
var bit SHT_DATA -- data pin, data flows in both directions
var bit SHT_DATA_DIR -- direction of data pin
Still to do: switching heating on/off

Sources

http://www.sensirion.com/en/01_humidity_sensors/00_humidity_sensors.htm

Routines

  • read_celsius_temp_sht - Procedure
  • read_centicelsius_temp_sht - Procedure
  • read_hum_sht - Procedure
  • read_hum_word_sht - Procedure
  • read_raw_hum_sht - Procedure
  • read_raw_temp_sht - Procedure
  • sht_conn_reset - Procedure
  • sht_get_data - Procedure
  • sht_put_ack - Procedure
  • sht_put_data - Procedure
  • sht_reset - Procedure
  • sht_start - Procedure
  • sht_wait_ack - Procedure


i2c_hardware2.jal - JALLIB Library Documentation

i2c_hardware2.jal JALLIB LIBRARY

Title

I2C hardware2 library.

Author

Rob Jansen, Copyright (C) 2025..2025, all rights reserved., Adapted-by:

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Hardware implementation of I2C 2 (single) master.
Define i2c pins like:
alias i2c_scl2_direction is pin_c4_direction
alias i2c_sda2_direction is pin_c5_direction
Optional settings:
const bit _i2c_level2 = TRUE -- i2c levels (not SMB), default.
const byte _i2c_bus_speed2 = 1 -- 100kHz, default
Note that _i2c_bus_speed2 can be overruled by a user defined bus speed.
The range is depending on the target_clock. This is an optional setting:
const i2c_USER_BUS_SPEED2 = 50_000 -- Bus speed is in Hz.
The user can define a timeout as to prevent a hangup in case something goes wrong.
The timing is not exact but uses a reference of around 1 us as miniumum.
This is an optional setting:
const word I2C_HARDWARE_TIMEOUT2 = 10_000 -- Timeout is al least 10 ms.

Sources

Based on i2c_hardware.jal by Joep Suijs.

Aliases to support other PICs.

Routines

  • i2c_initialize2 - Procedure
  • i2c_receive_byte2 - Function returns byte
  • i2c_restart2 - Procedure
  • i2c_start2 - Procedure
  • i2c_stop2 - Procedure
  • i2c_transmit_byte2 - Function returns bit


i2c_hardware.jal - JALLIB Library Documentation

i2c_hardware.jal JALLIB LIBRARY

Title

I2C hardware library

Author

Stef Mientki, Copyright (C) 2005..2025, all rights reserved., Adapted-by: Joep Suijs, Albert Faber, Rob Jansen

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Hardware implementation of I2C 1 (single) master.
Define i2c pins like:
alias i2c_scl_direction is pin_c3_direction
alias i2c_sda_direction is pin_c4_direction
Optional settings:
const bit _i2c_level2 = TRUE -- i2c levels (not SMB), default.
const byte _i2c_bus_speed2 = 1 -- 100kHz, default
Note that _i2c_bus_speed can be overruled by a user defined bus speed.
The range is depending on the target_clock. This is an optional setting:
const I2C_USER_BUS_SPEED = 50_000 -- Bus speed is in Hz.
The use can define a timeout as to prevent a hangup in case something goes wrong.
The timing is not exact but uses a reference of around 1 us as miniumum.
This is an optional setting:
const word I2C_HARDWARE_TIMEOUT = 10_000 -- Timeout is al least 10 ms.

Aliases to support other PICs.

Routines

  • i2c_initialize - Procedure
  • i2c_receive_byte - Function returns byte
  • i2c_restart - Procedure
  • i2c_start - Procedure
  • i2c_stop - Procedure
  • i2c_transmit_byte - Function returns bit


i2c_hw_slave.jal - JALLIB Library Documentation

i2c_hw_slave.jal JALLIB LIBRARY

Title

i2c_hardware slave procedures

Author

Sebastien Lelong, Copyright (c) 2008..2019, all rights reserved., Adapted-by: Joep Suijs, Albert Faber, Rob Hamerling, Rob Jansen

Compiler

>=2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Common and useful functions and procedure to implement an I2C slave

Notes

Modifications by Rob Hamerling (may 2017)
- Clock stretching - when control-bit present - enabled for all types of core.
Aliases to support other PICs.

Routines

  • i2c_hw_slave_init - Procedure
  • i2c_hw_slave_read_i2c - Function returns byte
  • i2c_hw_slave_write_i2c - Procedure


i2c_hw_slave_init - JALlib Procedures Help

i2c_hw_slave_init JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_init(byte in height_bits_icaddress) is

Description

setup an i2c slave, with low address (not high addresses coded with 10-bits)
The passed address must be 8-bits long: it's a 7-bits address + the 8th R/W bit
A global "i2c_enable_start_stop_interrupts" constant can be defined to so
interrupts are generated on Start/Stop signals.
/!\ careful: calling this procedure will enable interrupts (global, peripherals and i2c)

Include

To use this procedure, include the library:

include i2c_hw_slave

Parameters

  • height_bits_icaddress - byte in

Return Value

None

Example

From sample file: 18f2620_i2c_hw_slave_msg.jal

-- Title: Test program for i2c hardware slave, message interface implementation
-- Author: Joep Suijs, Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- using the message interface lib. Basically, this i2c slave waits for
-- a full message to arrive and then calls a user routine to process the message and
-- (optional) prepare a response.
-- --
-- Conventions:
-- S = create (re)start state
-- P = create stop state
-- E4W = master writes 0x4E
-- R   = master reads and ACKs
-- N   = master reads and NACKs
-- --
-- s5Cw80ws5Dwrnp - reads application code and version (0x31 0x01)
-- s5Cw90w00wp    - LED off
-- s5Cw90wFFwp    - LED on
-- --
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2620_js.jal
--    * test : test_i2c_hw_slave_msg.jal
--

;@jallib section chipdef
-- chip setup
include 18f2620

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                            -- allow LVP
pragma target  WDT CONTROL                            -- watchdog software controlled

WDTCON_SWDTEN = OFF                                   -- disable watchdog
;@jallib section led
-- LED IO definition
alias led             is pin_c5
alias led_direction   is pin_c5_direction
led_direction = output

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

const byte str1[] = "Test i2c hardware slave - msg interface.\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

-- ---------------
-- setup i2c slave
-- ---------------
const byte I2C_BUFFER_SIZE = 40
include i2c_hw_slave_msg

-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- --------------------------------------------------------------------
-- i2c_process_message - User code for i2c slave
-- --------------------------------------------------------------------
-- This code is called from the ISR, every time the i2c slave module
-- received a serie of bytes.
-- The ISR logic assures this procedure is called exactly once for
-- each messagae.
-- --------------------------------------------------------------------
procedure i2c_process_message(byte in byte_count) is
   if (i2c_buffer[0] == 0x80) then

      if (byte_count == 1) then
         -- cmd 0x80 - request version
         i2c_buffer[0]   = 0x3C         -- application code
         i2c_buffer[1]   = 0x01         -- version
      end if

   elsif (i2c_buffer[0] == 0x90) then

      if (byte_count == 2) then
         -- cmd 0x90 - turn LED off or on
         if (i2c_buffer[1] == 0) then
            LED = off
         else
            LED = on
         end if
      elsif (byte_count == 1) then
         -- cmd 0x90 without params: request for led status
         if (LED) then
            i2c_buffer[0] = 0xFF
         else
            i2c_buffer[0] = 0x00
         end if
      end if

   end if

end procedure

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop

end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave.jal


i2c_hw_slave_isr.jal - JALLIB Library Documentation

i2c_hw_slave_isr.jal JALLIB LIBRARY

Title

i2c hardware slave ISR

Author

Sebastien Lelong, Joep Suijs, Copyright (c) 2008..2019, all rights reserved., Adapted-by: Joep Suijs, Albert Faber, Rob Jansen

Compiler

>=2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides an ISR to implement
a stateful i2c hardware slave. This is a jalv2 implementation of
Microchip Application Note AN734.
--
According to AN734, there are 5 possible i2c states. During ISR, each
of this states are detected. This ISR provides a standard skeleton to implement
an i2c hardware slaves, while client code must implement several callbacks
the ISR is expecting to call while processing states.
--
Here there are:
- procedure i2c_hw_slave_on_state_1(byte in _trash):
called when i2c address matches (master starts a talk)
--
- procedure i2c_hw_slave_on_state_2(byte in rcv):
called when master is writing a byte. Slave is thus
receiving this byte. This callback takes this bytes as
argument
--
- procedure i2c_hw_slave_on_state_3():
called when master wants to read a byte from slave. Thus,
slave should send a byte (for instance, using i2c_hw_slave_write_i2c
from i2c_hw_slave.jal library)
--
- procedure i2c_hw_slave_on_state_4():
called when master still wants to read a byte from slave. That is,
master required to read (state 3) and now still want to read a byte
--
- procedure i2c_hw_slave_on_state_5():
called when master does not want to talk to slave anymore
usually a good place to reset data or slave's logic
--
- procedure i2c_hw_slave_on_error():
called when something wrong happens. You can do what you want in
this case, like resetting the PIC, log some information using usart, ...
=> called any cases other than states 1, 2, 3, 4 or 5

Sources

- AN734: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011798
enable line below to enable testing of the clock stretching feature
it will add an additional delay of 200us in the interrupt handler
so were sure that clock stretching is required for 100 KHz I2C operation

const bit I2C_HW_SLAVE_TEST_CLOCK_STRETCHING = 1

i2c ISR handler. Detects states a call appropriate procedures

Routines

  • i2c_hw_slave_isr_handler - Procedure


i2c_hw_slave_msg.jal - JALLIB Library Documentation

i2c_hw_slave_msg.jal JALLIB LIBRARY

Title

i2c hardware slave Message Interface

Author

Sebastien Lelong, Joep Suijs, Copyright (c) 2008-2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides an message interface to i2c hardware slave.
It relies on the jalv2 implementation of Microchip Application Note AN734.
--
The user needs to supply a procedure to process the received message.
Basically, this i2c slave waits for a full message to arrive. Then it calls
the user procedure to process the message and (optional) prepare a response.
Subsequently, this lib will pass the response data over to the master, if
it wants to have them.
See corresponding sample for more details.
--

Sources

- AN734: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011798

prototype

Constants and Variables

i2c_enable_start_stop_interrupts - const bit = true

Routines

  • i2c_call_process_message - Procedure
  • i2c_hw_slave_on_error - Procedure
  • i2c_hw_slave_on_start - Procedure
  • i2c_hw_slave_on_state_1 - Procedure
  • i2c_hw_slave_on_state_2 - Procedure
  • i2c_hw_slave_on_state_3 - Procedure
  • i2c_hw_slave_on_state_4 - Procedure
  • i2c_hw_slave_on_state_5 - Procedure
  • i2c_hw_slave_on_stop - Procedure


i2c_hw_slave_on_error - JAL Language Syntax Reference

i2c_hw_slave_on_error SYNTAX

Description:
this sample shows how to implements an i2c hardware slave, -- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for -- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b") -- -- -- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples, -- which is the master part. -- -- This file has been generated by jallib.py from: -- * board: board_18f2520_js.jal -- * test : test_i2c_hw_slave_echo.jal -- ;@jallib section chipdef -- chip setup include 18f2520 pragma target clock 20_000_000 pragma target OSC hs pragma target LVP enabled -- allow LVP pragma target WDT CONTROL -- watchdog software controlled WDTCON_SWDTEN = OFF -- disable watchdog ;@jallib section led -- LED IO definition alias led is pin_c5 alias led_direction is pin_c5_direction led_direction = output include i2c_hw_slave -- this will be the slave address. It looks like: -- 0b_0101_1100 -- => 0b_0101_110 : 7-bits address -- => 0 : 8th bit is to specify read or write operation. -- Value can be anything, it does not matter while init const byte SLAVE_ADDRESS = 0x5C i2c_hw_slave_init(SLAVE_ADDRESS) -- will store what to send back to master -- so if we get "a", we need to store "a" + 1 var byte data -- Before including i2c_hw_slave_isr library, several callbacks -- must be defined (callbacks are procedure which supposed to be defined -- and be called on appriopriate time) -- Since all those callbacks are called once per state (no other calls -- in the program), it is suggested to use "pragma inline", to save -- stack usage -- this callback is used when something wrong happened -- during communication between master and us

Generated by JAL Syntax Documentation System | Source: DITA


i2c_hw_slave_on_state_1 - JALlib Procedures Help

i2c_hw_slave_on_state_1 JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_on_state_1(byte in _trash) is

Description

this callback is used when master wants to talk to us
and our i2c address has been recognized

Include

To use this procedure, include the library:

include i2c_hw_slave_msg

Parameters

  • _trash - byte in

Return Value

None

Example

From sample file: 18f2550_i2c_hw_slave_echo.jal

-- Title: Test program for i2c hardware slave, stateful implementation
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for
-- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b")
-- --
-- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples,
-- which is the master part.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_i2c_hw_slave_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib section led
-- LED IO definition
alias led             is pin_a5
alias led_direction   is pin_a5_direction
led_direction = output

include i2c_hw_slave
-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- will store what to send back to master
-- so if we get "a", we need to store "a" + 1
var byte data

-- Before including i2c_hw_slave_isr library, several callbacks
-- must be defined (callbacks are procedure which supposed to be defined
-- and be called on appriopriate time)

-- Since all those callbacks are called once per state (no other calls
-- in the program), it is suggested to use "pragma inline", to save
-- stack usage

-- this callback is used when something wrong happened
-- during communication between master and us
procedure i2c_hw_slave_on_error() is
   pragma inline
   -- Just tell user user something's got wrong
   forever loop
      led = on
      _usec_delay(200000)
      led = off
      _usec_delay(200000)
   end loop
end procedure

-- this callback is used when master wants to talk to us
-- and our i2c address has been recognized
procedure i2c_hw_slave_on_state_1(byte in _trash) is
   pragma inline
   -- _trash is read from master, but it's a dummy data
   -- usually (always ?) ignored
end procedure

-- This callback is used when master sends a data byte
procedure i2c_hw_slave_on_state_2(byte in rcv) is
   pragma inline
   -- ultimate data processing... :)
   data = rcv + 1
end procedure

-- this callback is used when master wants to read something
-- from us. It should use i2c_hw_slave_write() to send something
procedure i2c_hw_slave_on_state_3() is
   pragma inline
   i2c_hw_slave_write_i2c(data)
end procedure

-- this callback is used when master, after having read something,
-- still wants to read and get data from us.
procedure i2c_hw_slave_on_state_4() is
   pragma inline
   -- This shouldn't occur in our i2c echo example
   i2c_hw_slave_on_error()
end procedure

-- this callback is used when master does not want to talk
-- with us anymore... This is an appropriate place to reset
-- data for instance
procedure i2c_hw_slave_on_state_5() is
   pragma inline
   data = 0
end procedure

-- callbacks are defined, now include ISR
include i2c_hw_slave_isr

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop
end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave_msg.jal


i2c_hw_slave_on_state_2 - JALlib Procedures Help

i2c_hw_slave_on_state_2 JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_on_state_2(byte in rcv) is

Description

This callback is used when master sends a data byte

Include

To use this procedure, include the library:

include i2c_hw_slave_msg

Parameters

  • rcv - byte in

Return Value

None

Example

From sample file: 18f2550_i2c_hw_slave_echo.jal

-- Title: Test program for i2c hardware slave, stateful implementation
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for
-- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b")
-- --
-- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples,
-- which is the master part.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_i2c_hw_slave_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib section led
-- LED IO definition
alias led             is pin_a5
alias led_direction   is pin_a5_direction
led_direction = output

include i2c_hw_slave
-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- will store what to send back to master
-- so if we get "a", we need to store "a" + 1
var byte data

-- Before including i2c_hw_slave_isr library, several callbacks
-- must be defined (callbacks are procedure which supposed to be defined
-- and be called on appriopriate time)

-- Since all those callbacks are called once per state (no other calls
-- in the program), it is suggested to use "pragma inline", to save
-- stack usage

-- this callback is used when something wrong happened
-- during communication between master and us
procedure i2c_hw_slave_on_error() is
   pragma inline
   -- Just tell user user something's got wrong
   forever loop
      led = on
      _usec_delay(200000)
      led = off
      _usec_delay(200000)
   end loop
end procedure

-- this callback is used when master wants to talk to us
-- and our i2c address has been recognized
procedure i2c_hw_slave_on_state_1(byte in _trash) is
   pragma inline
   -- _trash is read from master, but it's a dummy data
   -- usually (always ?) ignored
end procedure

-- This callback is used when master sends a data byte
procedure i2c_hw_slave_on_state_2(byte in rcv) is
   pragma inline
   -- ultimate data processing... :)
   data = rcv + 1
end procedure

-- this callback is used when master wants to read something
-- from us. It should use i2c_hw_slave_write() to send something
procedure i2c_hw_slave_on_state_3() is
   pragma inline
   i2c_hw_slave_write_i2c(data)
end procedure

-- this callback is used when master, after having read something,
-- still wants to read and get data from us.
procedure i2c_hw_slave_on_state_4() is
   pragma inline
   -- This shouldn't occur in our i2c echo example
   i2c_hw_slave_on_error()
end procedure

-- this callback is used when master does not want to talk
-- with us anymore... This is an appropriate place to reset
-- data for instance
procedure i2c_hw_slave_on_state_5() is
   pragma inline
   data = 0
end procedure

-- callbacks are defined, now include ISR
include i2c_hw_slave_isr

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop
end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave_msg.jal


i2c_hw_slave_on_state_3 - JALlib Procedures Help

i2c_hw_slave_on_state_3 JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_on_state_3() is

Description

this callback is used when master wants to read something
from us. It should use i2c_hw_slave_write() to send something

Include

To use this procedure, include the library:

include i2c_hw_slave_msg

Parameters

None

Return Value

None

Example

From sample file: 18f2550_i2c_hw_slave_echo.jal

-- Title: Test program for i2c hardware slave, stateful implementation
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for
-- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b")
-- --
-- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples,
-- which is the master part.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_i2c_hw_slave_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib section led
-- LED IO definition
alias led             is pin_a5
alias led_direction   is pin_a5_direction
led_direction = output

include i2c_hw_slave
-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- will store what to send back to master
-- so if we get "a", we need to store "a" + 1
var byte data

-- Before including i2c_hw_slave_isr library, several callbacks
-- must be defined (callbacks are procedure which supposed to be defined
-- and be called on appriopriate time)

-- Since all those callbacks are called once per state (no other calls
-- in the program), it is suggested to use "pragma inline", to save
-- stack usage

-- this callback is used when something wrong happened
-- during communication between master and us
procedure i2c_hw_slave_on_error() is
   pragma inline
   -- Just tell user user something's got wrong
   forever loop
      led = on
      _usec_delay(200000)
      led = off
      _usec_delay(200000)
   end loop
end procedure

-- this callback is used when master wants to talk to us
-- and our i2c address has been recognized
procedure i2c_hw_slave_on_state_1(byte in _trash) is
   pragma inline
   -- _trash is read from master, but it's a dummy data
   -- usually (always ?) ignored
end procedure

-- This callback is used when master sends a data byte
procedure i2c_hw_slave_on_state_2(byte in rcv) is
   pragma inline
   -- ultimate data processing... :)
   data = rcv + 1
end procedure

-- this callback is used when master wants to read something
-- from us. It should use i2c_hw_slave_write() to send something
procedure i2c_hw_slave_on_state_3() is
   pragma inline
   i2c_hw_slave_write_i2c(data)
end procedure

-- this callback is used when master, after having read something,
-- still wants to read and get data from us.
procedure i2c_hw_slave_on_state_4() is
   pragma inline
   -- This shouldn't occur in our i2c echo example
   i2c_hw_slave_on_error()
end procedure

-- this callback is used when master does not want to talk
-- with us anymore... This is an appropriate place to reset
-- data for instance
procedure i2c_hw_slave_on_state_5() is
   pragma inline
   data = 0
end procedure

-- callbacks are defined, now include ISR
include i2c_hw_slave_isr

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop
end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave_msg.jal


i2c_hw_slave_on_state_4 - JALlib Procedures Help

i2c_hw_slave_on_state_4 JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_on_state_4() is

Description

this callback is used when master, after having read something,
still wants to read and get data from us.

Include

To use this procedure, include the library:

include i2c_hw_slave_msg

Parameters

None

Return Value

None

Example

From sample file: 18f2550_i2c_hw_slave_echo.jal

-- Title: Test program for i2c hardware slave, stateful implementation
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for
-- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b")
-- --
-- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples,
-- which is the master part.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_i2c_hw_slave_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib section led
-- LED IO definition
alias led             is pin_a5
alias led_direction   is pin_a5_direction
led_direction = output

include i2c_hw_slave
-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- will store what to send back to master
-- so if we get "a", we need to store "a" + 1
var byte data

-- Before including i2c_hw_slave_isr library, several callbacks
-- must be defined (callbacks are procedure which supposed to be defined
-- and be called on appriopriate time)

-- Since all those callbacks are called once per state (no other calls
-- in the program), it is suggested to use "pragma inline", to save
-- stack usage

-- this callback is used when something wrong happened
-- during communication between master and us
procedure i2c_hw_slave_on_error() is
   pragma inline
   -- Just tell user user something's got wrong
   forever loop
      led = on
      _usec_delay(200000)
      led = off
      _usec_delay(200000)
   end loop
end procedure

-- this callback is used when master wants to talk to us
-- and our i2c address has been recognized
procedure i2c_hw_slave_on_state_1(byte in _trash) is
   pragma inline
   -- _trash is read from master, but it's a dummy data
   -- usually (always ?) ignored
end procedure

-- This callback is used when master sends a data byte
procedure i2c_hw_slave_on_state_2(byte in rcv) is
   pragma inline
   -- ultimate data processing... :)
   data = rcv + 1
end procedure

-- this callback is used when master wants to read something
-- from us. It should use i2c_hw_slave_write() to send something
procedure i2c_hw_slave_on_state_3() is
   pragma inline
   i2c_hw_slave_write_i2c(data)
end procedure

-- this callback is used when master, after having read something,
-- still wants to read and get data from us.
procedure i2c_hw_slave_on_state_4() is
   pragma inline
   -- This shouldn't occur in our i2c echo example
   i2c_hw_slave_on_error()
end procedure

-- this callback is used when master does not want to talk
-- with us anymore... This is an appropriate place to reset
-- data for instance
procedure i2c_hw_slave_on_state_5() is
   pragma inline
   data = 0
end procedure

-- callbacks are defined, now include ISR
include i2c_hw_slave_isr

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop
end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave_msg.jal


i2c_hw_slave_on_state_5 - JALlib Procedures Help

i2c_hw_slave_on_state_5 JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_on_state_5() is

Description

this callback is used when master does not want to talk
with us anymore... This is an appropriate place to reset
data for instance

Include

To use this procedure, include the library:

include i2c_hw_slave_msg

Parameters

None

Return Value

None

Example

From sample file: 18f2550_i2c_hw_slave_echo.jal

-- Title: Test program for i2c hardware slave, stateful implementation
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for
-- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b")
-- --
-- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples,
-- which is the master part.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_i2c_hw_slave_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib section led
-- LED IO definition
alias led             is pin_a5
alias led_direction   is pin_a5_direction
led_direction = output

include i2c_hw_slave
-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- will store what to send back to master
-- so if we get "a", we need to store "a" + 1
var byte data

-- Before including i2c_hw_slave_isr library, several callbacks
-- must be defined (callbacks are procedure which supposed to be defined
-- and be called on appriopriate time)

-- Since all those callbacks are called once per state (no other calls
-- in the program), it is suggested to use "pragma inline", to save
-- stack usage

-- this callback is used when something wrong happened
-- during communication between master and us
procedure i2c_hw_slave_on_error() is
   pragma inline
   -- Just tell user user something's got wrong
   forever loop
      led = on
      _usec_delay(200000)
      led = off
      _usec_delay(200000)
   end loop
end procedure

-- this callback is used when master wants to talk to us
-- and our i2c address has been recognized
procedure i2c_hw_slave_on_state_1(byte in _trash) is
   pragma inline
   -- _trash is read from master, but it's a dummy data
   -- usually (always ?) ignored
end procedure

-- This callback is used when master sends a data byte
procedure i2c_hw_slave_on_state_2(byte in rcv) is
   pragma inline
   -- ultimate data processing... :)
   data = rcv + 1
end procedure

-- this callback is used when master wants to read something
-- from us. It should use i2c_hw_slave_write() to send something
procedure i2c_hw_slave_on_state_3() is
   pragma inline
   i2c_hw_slave_write_i2c(data)
end procedure

-- this callback is used when master, after having read something,
-- still wants to read and get data from us.
procedure i2c_hw_slave_on_state_4() is
   pragma inline
   -- This shouldn't occur in our i2c echo example
   i2c_hw_slave_on_error()
end procedure

-- this callback is used when master does not want to talk
-- with us anymore... This is an appropriate place to reset
-- data for instance
procedure i2c_hw_slave_on_state_5() is
   pragma inline
   data = 0
end procedure

-- callbacks are defined, now include ISR
include i2c_hw_slave_isr

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop
end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave_msg.jal


i2c_hw_slave_write_i2c - JALlib Procedures Help

i2c_hw_slave_write_i2c JALLIB PROCEDURE

Signature

procedure i2c_hw_slave_write_i2c(byte in what) is

Description

write a byte to i2c bus

Include

To use this procedure, include the library:

include i2c_hw_slave

Parameters

  • what - byte in

Return Value

None

Example

From sample file: 18f2550_i2c_hw_slave_echo.jal

-- Title: Test program for i2c hardware slave, stateful implementation
-- Author: Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- based in i2c_hw_slave_isr.jal library. Basically, this i2c slave waits for
-- a byte, and when required, it sends byte + 1 (send "a", you'll get a "b")
-- --
-- This sample is aimed to be used with *_i2c_hw_master_echo.jal samples,
-- which is the master part.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_i2c_hw_slave_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib section led
-- LED IO definition
alias led             is pin_a5
alias led_direction   is pin_a5_direction
led_direction = output

include i2c_hw_slave
-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0x5C
i2c_hw_slave_init(SLAVE_ADDRESS)

-- will store what to send back to master
-- so if we get "a", we need to store "a" + 1
var byte data

-- Before including i2c_hw_slave_isr library, several callbacks
-- must be defined (callbacks are procedure which supposed to be defined
-- and be called on appriopriate time)

-- Since all those callbacks are called once per state (no other calls
-- in the program), it is suggested to use "pragma inline", to save
-- stack usage

-- this callback is used when something wrong happened
-- during communication between master and us
procedure i2c_hw_slave_on_error() is
   pragma inline
   -- Just tell user user something's got wrong
   forever loop
      led = on
      _usec_delay(200000)
      led = off
      _usec_delay(200000)
   end loop
end procedure

-- this callback is used when master wants to talk to us
-- and our i2c address has been recognized
procedure i2c_hw_slave_on_state_1(byte in _trash) is
   pragma inline
   -- _trash is read from master, but it's a dummy data
   -- usually (always ?) ignored
end procedure

-- This callback is used when master sends a data byte
procedure i2c_hw_slave_on_state_2(byte in rcv) is
   pragma inline
   -- ultimate data processing... :)
   data = rcv + 1
end procedure

-- this callback is used when master wants to read something
-- from us. It should use i2c_hw_slave_write() to send something
procedure i2c_hw_slave_on_state_3() is
   pragma inline
   i2c_hw_slave_write_i2c(data)
end procedure

-- this callback is used when master, after having read something,
-- still wants to read and get data from us.
procedure i2c_hw_slave_on_state_4() is
   pragma inline
   -- This shouldn't occur in our i2c echo example
   i2c_hw_slave_on_error()
end procedure

-- this callback is used when master does not want to talk
-- with us anymore... This is an appropriate place to reset
-- data for instance
procedure i2c_hw_slave_on_state_5() is
   pragma inline
   data = 0
end procedure

-- callbacks are defined, now include ISR
include i2c_hw_slave_isr

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

-- just loop until interrupt is raised
forever loop
end loop

Generated by JALlib CHM Help System | Source: i2c_hw_slave.jal


i2c_initialize - JALlib Procedures Help

i2c_initialize JALLIB PROCEDURE

Signature

procedure i2c_initialize() is

Description

if the device has changed, change the speed if necessary

Include

To use this procedure, include the library:

include i2c_hardware

Parameters

None

Return Value

None

Example

From sample file: 16f877_i2c_sw_l1.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l1.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details)
;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB;  i2c_hw only)

;include i2c_hardware
include i2c_software

i2c_initialize()

var byte i2c_tx_buffer[10]
var byte i2c_rx_buffer[10]

include i2c_level1

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i

forever loop

   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
;   i2c_tx_buffer[0] = 0x12  -- high byte address within i2c eeprom
;   i2c_tx_buffer[1] = 0x34  -- low byte address within i2c eeprom
;   r = i2c_send_receive(0xA0, 2, 3)

   -- same as above
   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
   r = i2c_receive_wordaddr(0xA0, 0x0000, 3)

   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_byte_hex(serial_hw_data, i2c_rx_buffer[0]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[1]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[2]);
   serial_hw_data = " "

   -- write part (increment 3rd byte at 0x0002)
   i2c_tx_buffer[0] = 0x12     -- high byte addr within i2c eeprom
   i2c_tx_buffer[1] = 0x34 + 2 -- low byte addr within i2c eeprom
   i2c_tx_buffer[2] = i2c_rx_buffer[2] + 1  -- data
   r = i2c_send_receive(0xA0, 3, 0)
   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_hardware.jal


i2c_initialize2 - JALlib Procedures Help

i2c_initialize2 JALLIB PROCEDURE

Signature

procedure i2c_initialize2() is

Description

if the device has changed, change the speed if necessary

Include

To use this procedure, include the library:

include i2c_hardware2

Parameters

None

Return Value

None

Example

From sample file: 16f18325_i2c_hw2_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Sample program for i2c_hardware2.jal.
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Level 0 i2c test program. Interact with a 24lc256 i2c eeprom using
--              the i2c primitives and i2c hardware 2.
--
-- Sources: Based on the sample program of Joep Suijs.
--
--
include 16f18325                    -- target PICmicro
--
-- This program uses the internal oscillator at 16 MHz.
pragma target clock   16_000_000    -- oscillator frequency
pragma target OSC      OFF          -- internal oscillator
pragma target RSTOSC   HFINT32      -- select 32 MHz
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

OSCCON1_NDIV = 0b0001               -- Fosc 16 MHz

enable_digital_io()                 -- Don't forget this otherwise I2C will not work.

-- Assign the pins. This must always be done to let it work even for
-- the default pin assignment.
include pps
pps_control_lock(FALSE)
-- USART pin assignment changed as to use the default for I2C 2.
RC2PPS = PPS_TX   -- USART transmit
RXPPS  = PPS_RC3  -- USART receive
-- I2C 2 bi-direactional pin assignments (default).
RC4PPS = PPS_SCK2     -- Output I2C 2 clock for EEPROM
RC5PPS = PPS_SDA2     -- Output I2C 2 data for EEPROM
SSP2CLKPPS  = PPS_RC4 -- Input  I2C 2 clock for EEPROM
SSP2DATPPS  = PPS_RC5 -- Input  I2C 2 data for EEPROM
pps_control_lock(TRUE)

-- I2C IO definition, using I2C hardware 2.
alias i2c_scl2_direction is pin_c4_direction -- pin 6 for 14 pin DIP.
alias i2c_sda2_direction is pin_c5_direction -- pin 5 for 14 pin DIP.

-- USART setup.
alias pin_RX_direction is pin_C3_direction -- Pin 7 of 14 pin DIP.
alias pin_TX_direction is pin_C2_direction -- Pin 8 of 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- EEPROM address. Change when needed.
const byte EEPROM_DEVICE_ADDRESS = 0xAE

include i2c_hardware2
i2c_initialize2()

-- we're alive
print_string(serial_hw_data, "Test.\r\n")

var bit r
var byte i

forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte).
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r = i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x00) -- memory address low  byte

   i2c_restart2()
   -- i2c address for read (of memory from eeprom)
   r = r & i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS | 0x01)

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(FALSE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop2()

   -- write part (relies on var i, we just read!)
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r =     i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x02) -- memory address low  byte
   -- Only change the third position.
   r = r & i2c_transmit_byte2(i+1)  -- data byte
   i2c_stop2()

   print_crlf(serial_hw_data)

   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: i2c_hardware2.jal


i2c_level1.jal - JALLIB Library Documentation

i2c_level1.jal JALLIB LIBRARY

Title

i2c_hardware

Author

Joep Suijs, Copyright (C) 2008 Joep Suijs, Adapted-by:

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Level1 implementation of I2C (single) master.
User must define the rx and tx buffer like:
var byte i2c_tx_buffer[10]
var byte i2c_rx_buffer[10]
tx_buffer[] should be at least 2 bytes long to support i2c_receive_wordaddr.
if you desperatly want to use a 1-byte tx buffer, define (besides the buffer):
const single_byte_tx_buffer = 1

some validations

-----------------------------------------------------------------------------
i2c_send_receive - send a string to an i2c slave and receive bytes back
-----------------------------------------------------------------------------
This funtion uses two global i2c buffers, one for transmit (tx) and one for
receive (rx). The address of the slave (higher 7 bits), number of bytes to
transmit and number of bytes to receive are parameters.
returns true if all went well.
-----------------------------------------------------------------------------

Routines

  • i2c_receive_byteaddr - Function returns bit
  • i2c_receive_wordaddr - Function returns bit
  • i2c_send_receive - Function returns bit


i2c_receive_byte - JALlib Procedures Help

i2c_receive_byte JALLIB FUNCTION

Signature

function i2c_receive_byte(bit in ACK ) return byte is

Description

start receiving of a byte and waits till finished or timeout (if defined)
if param ACK is true, the byte is acknowledged and next bytes can be received.
if param ACK is false, the byte is nacked and a stop *should be* sent.
note: this behavior is inverted from the line level and orignal library, but
consistent with the i2c_software library.

Include

To use this procedure, include the library:

include i2c_hardware

Parameters

  • ACK - bit in

Return Value

byte - Function return value

Example

From sample file: 16f877_i2c_sw_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l0.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i
forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x00) -- memory address low  byte

   i2c_restart()
   r = r & i2c_transmit_byte(0xA1) -- i2c address for read (of memory from eeprom)

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(false)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop()

   -- write part (relies on var i, we just read!)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x02) -- memory address low  byte
   r = r & i2c_transmit_byte(i+1)  -- data byte
   i2c_stop()

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_hardware.jal


i2c_receive_byte2 - JALlib Procedures Help

i2c_receive_byte2 JALLIB FUNCTION

Signature

function i2c_receive_byte2(bit in ACK) return byte is

Description

start receiving of a byte and waits till finished or timeout (if defined)
if param ACK is TRUE, the byte is acknowledged and next bytes can be received.
if param ACK is FALSE, the byte is nacked and a stop *should be* sent.

Include

To use this procedure, include the library:

include i2c_hardware2

Parameters

  • ACK - bit in

Return Value

byte - Function return value

Example

From sample file: 16f18325_i2c_hw2_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Sample program for i2c_hardware2.jal.
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Level 0 i2c test program. Interact with a 24lc256 i2c eeprom using
--              the i2c primitives and i2c hardware 2.
--
-- Sources: Based on the sample program of Joep Suijs.
--
--
include 16f18325                    -- target PICmicro
--
-- This program uses the internal oscillator at 16 MHz.
pragma target clock   16_000_000    -- oscillator frequency
pragma target OSC      OFF          -- internal oscillator
pragma target RSTOSC   HFINT32      -- select 32 MHz
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

OSCCON1_NDIV = 0b0001               -- Fosc 16 MHz

enable_digital_io()                 -- Don't forget this otherwise I2C will not work.

-- Assign the pins. This must always be done to let it work even for
-- the default pin assignment.
include pps
pps_control_lock(FALSE)
-- USART pin assignment changed as to use the default for I2C 2.
RC2PPS = PPS_TX   -- USART transmit
RXPPS  = PPS_RC3  -- USART receive
-- I2C 2 bi-direactional pin assignments (default).
RC4PPS = PPS_SCK2     -- Output I2C 2 clock for EEPROM
RC5PPS = PPS_SDA2     -- Output I2C 2 data for EEPROM
SSP2CLKPPS  = PPS_RC4 -- Input  I2C 2 clock for EEPROM
SSP2DATPPS  = PPS_RC5 -- Input  I2C 2 data for EEPROM
pps_control_lock(TRUE)

-- I2C IO definition, using I2C hardware 2.
alias i2c_scl2_direction is pin_c4_direction -- pin 6 for 14 pin DIP.
alias i2c_sda2_direction is pin_c5_direction -- pin 5 for 14 pin DIP.

-- USART setup.
alias pin_RX_direction is pin_C3_direction -- Pin 7 of 14 pin DIP.
alias pin_TX_direction is pin_C2_direction -- Pin 8 of 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- EEPROM address. Change when needed.
const byte EEPROM_DEVICE_ADDRESS = 0xAE

include i2c_hardware2
i2c_initialize2()

-- we're alive
print_string(serial_hw_data, "Test.\r\n")

var bit r
var byte i

forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte).
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r = i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x00) -- memory address low  byte

   i2c_restart2()
   -- i2c address for read (of memory from eeprom)
   r = r & i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS | 0x01)

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(FALSE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop2()

   -- write part (relies on var i, we just read!)
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r =     i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x02) -- memory address low  byte
   -- Only change the third position.
   r = r & i2c_transmit_byte2(i+1)  -- data byte
   i2c_stop2()

   print_crlf(serial_hw_data)

   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: i2c_hardware2.jal


i2c_receive_wordaddr - JALlib Procedures Help

i2c_receive_wordaddr JALLIB FUNCTION

Signature

function i2c_receive_wordaddr(byte in i2c_address, word in addr, byte in i2c_rx_count) return bit is

Description

i2c_receive_wordaddr - send a word address and receive a string from an i2c slave

Include

To use this procedure, include the library:

include i2c_level1

Parameters

  • i2c_address - byte in
  • addr - word in
  • i2c_rx_count - byte in

Return Value

bit - Function return value

Example

From sample file: 16f877_i2c_sw_l1.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l1.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details)
;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB;  i2c_hw only)

;include i2c_hardware
include i2c_software

i2c_initialize()

var byte i2c_tx_buffer[10]
var byte i2c_rx_buffer[10]

include i2c_level1

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i

forever loop

   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
;   i2c_tx_buffer[0] = 0x12  -- high byte address within i2c eeprom
;   i2c_tx_buffer[1] = 0x34  -- low byte address within i2c eeprom
;   r = i2c_send_receive(0xA0, 2, 3)

   -- same as above
   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
   r = i2c_receive_wordaddr(0xA0, 0x0000, 3)

   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_byte_hex(serial_hw_data, i2c_rx_buffer[0]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[1]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[2]);
   serial_hw_data = " "

   -- write part (increment 3rd byte at 0x0002)
   i2c_tx_buffer[0] = 0x12     -- high byte addr within i2c eeprom
   i2c_tx_buffer[1] = 0x34 + 2 -- low byte addr within i2c eeprom
   i2c_tx_buffer[2] = i2c_rx_buffer[2] + 1  -- data
   r = i2c_send_receive(0xA0, 3, 0)
   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_level1.jal


i2c_reset_bus - JALlib Procedures Help

i2c_reset_bus JALLIB PROCEDURE

Signature

procedure i2c_reset_bus() is

Description

i2c_reset - initialize the i2c bus
The output latch values are always low,
the lines are switched open-collector fashion by
manipulating the direction registers.

Include

To use this procedure, include the library:

include i2c_reset_bus

Parameters

None

Return Value

None

Example

From sample file: 18f67k22_co2_i2c.jal

-- ------------------------------------------------------
-- Title: Measure CO2 via I2C bus with T6613 sensor  and pic18f67k22
--
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample CO2 measurement program with Microchip PIC18f67k22.
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 01 april 2014 12:07:11.
--
-- This file has been generated by hand (manually maintained)
--
-- ------------------------------------------------------
--

include 18f67k22    -- target PICmicro

-- external 20 MHz oscillator on pins OSC1 and OSC2
pragma target clock 20_000_000     -- oscillator frequency

-- configuration memory settings (fuses)
pragma target OSC       HSM         -- external oscillator
pragma target WDT       disabled    -- no watchdog
pragma target XINST     disabled    -- not supported by JalV2
pragma target DEBUG     disabled    -- no debugging
pragma target MCLR      external    -- reset externally

pragma target SOSCSEL   DIG         -- digital i/o on pin_c0 & pin_c1
pragma target RTCOSC    INTOSC      -- rtcc uses intrc

enable_digital_io()                -- make all pins digital I/O

-- i2c setup
const word _i2c_bus_speed = 1   -- * 100kHz
const bit _i2c_level = true     -- i2c levels (not SMB)

var bit  i2c_scl            is pin_c3              -- optional
var bit  i2c_scl_direction  is pin_c3_direction
var bit  i2c_sda            is pin_c4              -- optional
var bit  i2c_sda_direction  is pin_c4_direction

include i2c_reset_bus
i2c_reset_bus()
include i2c_hardware
i2c_initialize()
include co2_t6613_i2c     -- T6613 CO2 sensor via I2C

-- STERM LCD + KEYBOARD
-- single pin data connection to external handheld LCD + keyboard
var bit lcd_sterm_pin is pin_f4     -- Sterm LCD & keyboard
var bit lcd_sterm_pin_dir is pin_f4_direction
const byte LCD_ROWS = 4        --
const byte LCD_CHARS = 20
include lcd_sterm_master

include print

var word CO2 = 800
var byte loop_counter = 1

lcd_clear_screen()

forever loop

   CO2 = get_co2_ppm()

   lcd_cursor_position(0,0)   -- LINE 1
   lcd = "C" lcd = "O" lcd = "2" lcd = " "
   print_word_dec(lcd, CO2)
   lcd = " " lcd = "p" lcd = "p" lcd = "m"

   delay_1s(3)          -- CO2 sensor measures every 3 seconds

end loop

Generated by JALlib CHM Help System | Source: i2c_reset_bus.jal


i2c_reset_bus.jal - JALLIB Library Documentation

i2c_reset_bus.jal JALLIB LIBRARY

Title

i2c_reset_bus

Author

Wouter van Ooijen, Copyright (C) 1998, 1999 Wouter van Ooijen, Adapted-by: Joep Suijs, William Welch

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

reset / clear the i2c bus, bit-bang approach
--
-- Define i2c pins like:
alias i2c_scl is pin_c3
alias i2c_scl_direction is pin_c3_direction
alias i2c_sda is pin_c4
alias i2c_sda_direction is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
optional _i2c_scl_timeout to prevent system from hanging in a loop.
const _i2c_scl_timeout = 100 -- units are in bit-times.

TODO:

Routines

  • _i2c_bit_in - Procedure
  • _i2c_bit_out - Procedure
  • _i2c_start - Procedure
  • _i2c_stop - Procedure
  • _i2c_wait - Procedure
  • i2c_reset_bus - Procedure


i2c_restart - JALlib Procedures Help

i2c_restart JALLIB PROCEDURE

Signature

procedure i2c_restart() is

Description

Sends Restart bit and waits until finished or timeout (if defined)

Include

To use this procedure, include the library:

include i2c_hardware

Parameters

None

Return Value

None

Example

From sample file: 16f877_i2c_sw_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l0.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i
forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x00) -- memory address low  byte

   i2c_restart()
   r = r & i2c_transmit_byte(0xA1) -- i2c address for read (of memory from eeprom)

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(false)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop()

   -- write part (relies on var i, we just read!)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x02) -- memory address low  byte
   r = r & i2c_transmit_byte(i+1)  -- data byte
   i2c_stop()

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_hardware.jal


i2c_restart2 - JALlib Procedures Help

i2c_restart2 JALLIB PROCEDURE

Signature

procedure i2c_restart2() is

Description

Sends Restart bit and waits until finished or timeout (if defined)

Include

To use this procedure, include the library:

include i2c_hardware2

Parameters

None

Return Value

None

Example

From sample file: 16f18325_i2c_hw2_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Sample program for i2c_hardware2.jal.
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Level 0 i2c test program. Interact with a 24lc256 i2c eeprom using
--              the i2c primitives and i2c hardware 2.
--
-- Sources: Based on the sample program of Joep Suijs.
--
--
include 16f18325                    -- target PICmicro
--
-- This program uses the internal oscillator at 16 MHz.
pragma target clock   16_000_000    -- oscillator frequency
pragma target OSC      OFF          -- internal oscillator
pragma target RSTOSC   HFINT32      -- select 32 MHz
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

OSCCON1_NDIV = 0b0001               -- Fosc 16 MHz

enable_digital_io()                 -- Don't forget this otherwise I2C will not work.

-- Assign the pins. This must always be done to let it work even for
-- the default pin assignment.
include pps
pps_control_lock(FALSE)
-- USART pin assignment changed as to use the default for I2C 2.
RC2PPS = PPS_TX   -- USART transmit
RXPPS  = PPS_RC3  -- USART receive
-- I2C 2 bi-direactional pin assignments (default).
RC4PPS = PPS_SCK2     -- Output I2C 2 clock for EEPROM
RC5PPS = PPS_SDA2     -- Output I2C 2 data for EEPROM
SSP2CLKPPS  = PPS_RC4 -- Input  I2C 2 clock for EEPROM
SSP2DATPPS  = PPS_RC5 -- Input  I2C 2 data for EEPROM
pps_control_lock(TRUE)

-- I2C IO definition, using I2C hardware 2.
alias i2c_scl2_direction is pin_c4_direction -- pin 6 for 14 pin DIP.
alias i2c_sda2_direction is pin_c5_direction -- pin 5 for 14 pin DIP.

-- USART setup.
alias pin_RX_direction is pin_C3_direction -- Pin 7 of 14 pin DIP.
alias pin_TX_direction is pin_C2_direction -- Pin 8 of 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- EEPROM address. Change when needed.
const byte EEPROM_DEVICE_ADDRESS = 0xAE

include i2c_hardware2
i2c_initialize2()

-- we're alive
print_string(serial_hw_data, "Test.\r\n")

var bit r
var byte i

forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte).
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r = i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x00) -- memory address low  byte

   i2c_restart2()
   -- i2c address for read (of memory from eeprom)
   r = r & i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS | 0x01)

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(FALSE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop2()

   -- write part (relies on var i, we just read!)
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r =     i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x02) -- memory address low  byte
   -- Only change the third position.
   r = r & i2c_transmit_byte2(i+1)  -- data byte
   i2c_stop2()

   print_crlf(serial_hw_data)

   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: i2c_hardware2.jal


i2c_send_receive - JALlib Procedures Help

i2c_send_receive JALLIB FUNCTION

Signature

function i2c_send_receive(byte in i2c_address, byte in i2c_tx_count, byte in i2c_rx_count) return bit is

Description

i2c_send_receive - send a string to an i2c slave and receive bytes back
This funtion uses two global i2c buffers, one for transmit (tx) and one for
receive (rx). The address of the slave (higher 7 bits), number of bytes to
transmit and number of bytes to receive are parameters.
returns true if all went well.

Include

To use this procedure, include the library:

include i2c_level1

Parameters

  • i2c_address - byte in
  • i2c_tx_count - byte in
  • i2c_rx_count - byte in

Return Value

bit - Function return value

Example

From sample file: 16f877_i2c_sw_l1.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l1.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details)
;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB;  i2c_hw only)

;include i2c_hardware
include i2c_software

i2c_initialize()

var byte i2c_tx_buffer[10]
var byte i2c_rx_buffer[10]

include i2c_level1

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i

forever loop

   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
;   i2c_tx_buffer[0] = 0x12  -- high byte address within i2c eeprom
;   i2c_tx_buffer[1] = 0x34  -- low byte address within i2c eeprom
;   r = i2c_send_receive(0xA0, 2, 3)

   -- same as above
   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
   r = i2c_receive_wordaddr(0xA0, 0x0000, 3)

   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_byte_hex(serial_hw_data, i2c_rx_buffer[0]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[1]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[2]);
   serial_hw_data = " "

   -- write part (increment 3rd byte at 0x0002)
   i2c_tx_buffer[0] = 0x12     -- high byte addr within i2c eeprom
   i2c_tx_buffer[1] = 0x34 + 2 -- low byte addr within i2c eeprom
   i2c_tx_buffer[2] = i2c_rx_buffer[2] + 1  -- data
   r = i2c_send_receive(0xA0, 3, 0)
   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_level1.jal


i2c_software.jal - JALLIB Library Documentation

i2c_software.jal JALLIB LIBRARY

Title

i2c_software

Author

Wouter van Ooijen, Copyright (C) 1998, 1999 Wouter van Ooijen, Adapted-by: Joep Suijs.

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Software implementation of I2C (single) master.
--
-- Define i2c pins like:
alias i2c_scl is pin_c3
alias i2c_scl_direction is pin_c3_direction
alias i2c_sda is pin_c4
alias i2c_sda_direction is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
optional _i2c_scl_timeout to prevent system from hanging in a loop.
const _i2c_scl_timeout = 100 -- units are in bit-times.

TODO:

Routines

  • _i2c_bit_in - Procedure
  • _i2c_bit_out - Procedure
  • _i2c_wait - Procedure
  • i2c_initialize - Procedure
  • i2c_receive_byte - Function returns byte
  • i2c_restart - Procedure
  • i2c_start - Procedure
  • i2c_stop - Procedure
  • i2c_transmit_byte - Function returns bit


i2c_start - JALlib Procedures Help

i2c_start JALLIB PROCEDURE

Signature

procedure i2c_start() is

Description

Sends Start bit and waits until finished or timeout (if defined)

Include

To use this procedure, include the library:

include i2c_hardware

Parameters

None

Return Value

None

Example

From sample file: 16f877_i2c_sw_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l0.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i
forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x00) -- memory address low  byte

   i2c_restart()
   r = r & i2c_transmit_byte(0xA1) -- i2c address for read (of memory from eeprom)

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(false)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop()

   -- write part (relies on var i, we just read!)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x02) -- memory address low  byte
   r = r & i2c_transmit_byte(i+1)  -- data byte
   i2c_stop()

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_hardware.jal


i2c_start2 - JALlib Procedures Help

i2c_start2 JALLIB PROCEDURE

Signature

procedure i2c_start2() is

Description

Sends Start bit and waits until finished or timeout (if defined)

Include

To use this procedure, include the library:

include i2c_hardware2

Parameters

None

Return Value

None

Example

From sample file: 16f18325_i2c_hw2_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Sample program for i2c_hardware2.jal.
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Level 0 i2c test program. Interact with a 24lc256 i2c eeprom using
--              the i2c primitives and i2c hardware 2.
--
-- Sources: Based on the sample program of Joep Suijs.
--
--
include 16f18325                    -- target PICmicro
--
-- This program uses the internal oscillator at 16 MHz.
pragma target clock   16_000_000    -- oscillator frequency
pragma target OSC      OFF          -- internal oscillator
pragma target RSTOSC   HFINT32      -- select 32 MHz
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

OSCCON1_NDIV = 0b0001               -- Fosc 16 MHz

enable_digital_io()                 -- Don't forget this otherwise I2C will not work.

-- Assign the pins. This must always be done to let it work even for
-- the default pin assignment.
include pps
pps_control_lock(FALSE)
-- USART pin assignment changed as to use the default for I2C 2.
RC2PPS = PPS_TX   -- USART transmit
RXPPS  = PPS_RC3  -- USART receive
-- I2C 2 bi-direactional pin assignments (default).
RC4PPS = PPS_SCK2     -- Output I2C 2 clock for EEPROM
RC5PPS = PPS_SDA2     -- Output I2C 2 data for EEPROM
SSP2CLKPPS  = PPS_RC4 -- Input  I2C 2 clock for EEPROM
SSP2DATPPS  = PPS_RC5 -- Input  I2C 2 data for EEPROM
pps_control_lock(TRUE)

-- I2C IO definition, using I2C hardware 2.
alias i2c_scl2_direction is pin_c4_direction -- pin 6 for 14 pin DIP.
alias i2c_sda2_direction is pin_c5_direction -- pin 5 for 14 pin DIP.

-- USART setup.
alias pin_RX_direction is pin_C3_direction -- Pin 7 of 14 pin DIP.
alias pin_TX_direction is pin_C2_direction -- Pin 8 of 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- EEPROM address. Change when needed.
const byte EEPROM_DEVICE_ADDRESS = 0xAE

include i2c_hardware2
i2c_initialize2()

-- we're alive
print_string(serial_hw_data, "Test.\r\n")

var bit r
var byte i

forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte).
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r = i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x00) -- memory address low  byte

   i2c_restart2()
   -- i2c address for read (of memory from eeprom)
   r = r & i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS | 0x01)

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(FALSE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop2()

   -- write part (relies on var i, we just read!)
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r =     i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x02) -- memory address low  byte
   -- Only change the third position.
   r = r & i2c_transmit_byte2(i+1)  -- data byte
   i2c_stop2()

   print_crlf(serial_hw_data)

   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: i2c_hardware2.jal


i2c_stop - JALlib Procedures Help

i2c_stop JALLIB PROCEDURE

Signature

procedure i2c_stop() is

Description

Sends Stop bit and waits until finished or timeout (if defined)

Include

To use this procedure, include the library:

include i2c_hardware

Parameters

None

Return Value

None

Example

From sample file: 16f877_i2c_sw_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l0.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i
forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x00) -- memory address low  byte

   i2c_restart()
   r = r & i2c_transmit_byte(0xA1) -- i2c address for read (of memory from eeprom)

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(false)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop()

   -- write part (relies on var i, we just read!)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x02) -- memory address low  byte
   r = r & i2c_transmit_byte(i+1)  -- data byte
   i2c_stop()

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_hardware.jal


i2c_stop2 - JALlib Procedures Help

i2c_stop2 JALLIB PROCEDURE

Signature

procedure i2c_stop2() is

Description

Sends Stop bit and waits until finished or timeout (if defined)

Include

To use this procedure, include the library:

include i2c_hardware2

Parameters

None

Return Value

None

Example

From sample file: 16f18325_i2c_hw2_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Sample program for i2c_hardware2.jal.
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Level 0 i2c test program. Interact with a 24lc256 i2c eeprom using
--              the i2c primitives and i2c hardware 2.
--
-- Sources: Based on the sample program of Joep Suijs.
--
--
include 16f18325                    -- target PICmicro
--
-- This program uses the internal oscillator at 16 MHz.
pragma target clock   16_000_000    -- oscillator frequency
pragma target OSC      OFF          -- internal oscillator
pragma target RSTOSC   HFINT32      -- select 32 MHz
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

OSCCON1_NDIV = 0b0001               -- Fosc 16 MHz

enable_digital_io()                 -- Don't forget this otherwise I2C will not work.

-- Assign the pins. This must always be done to let it work even for
-- the default pin assignment.
include pps
pps_control_lock(FALSE)
-- USART pin assignment changed as to use the default for I2C 2.
RC2PPS = PPS_TX   -- USART transmit
RXPPS  = PPS_RC3  -- USART receive
-- I2C 2 bi-direactional pin assignments (default).
RC4PPS = PPS_SCK2     -- Output I2C 2 clock for EEPROM
RC5PPS = PPS_SDA2     -- Output I2C 2 data for EEPROM
SSP2CLKPPS  = PPS_RC4 -- Input  I2C 2 clock for EEPROM
SSP2DATPPS  = PPS_RC5 -- Input  I2C 2 data for EEPROM
pps_control_lock(TRUE)

-- I2C IO definition, using I2C hardware 2.
alias i2c_scl2_direction is pin_c4_direction -- pin 6 for 14 pin DIP.
alias i2c_sda2_direction is pin_c5_direction -- pin 5 for 14 pin DIP.

-- USART setup.
alias pin_RX_direction is pin_C3_direction -- Pin 7 of 14 pin DIP.
alias pin_TX_direction is pin_C2_direction -- Pin 8 of 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- EEPROM address. Change when needed.
const byte EEPROM_DEVICE_ADDRESS = 0xAE

include i2c_hardware2
i2c_initialize2()

-- we're alive
print_string(serial_hw_data, "Test.\r\n")

var bit r
var byte i

forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte).
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r = i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x00) -- memory address low  byte

   i2c_restart2()
   -- i2c address for read (of memory from eeprom)
   r = r & i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS | 0x01)

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(FALSE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop2()

   -- write part (relies on var i, we just read!)
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r =     i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x02) -- memory address low  byte
   -- Only change the third position.
   r = r & i2c_transmit_byte2(i+1)  -- data byte
   i2c_stop2()

   print_crlf(serial_hw_data)

   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: i2c_hardware2.jal


i2c_transmit_byte - JALlib Procedures Help

i2c_transmit_byte JALLIB FUNCTION

Signature

function i2c_transmit_byte(byte in data) return bit is

Description

Returns TRUE when OK and FALSE in case of an error or when a timeout occurs
(if defined)

Include

To use this procedure, include the library:

include i2c_hardware

Parameters

  • data - byte in

Return Value

bit - Function return value

Example

From sample file: 16f877_i2c_sw_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l0.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software
;include i2c_hardware

i2c_initialize()

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i
forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x00) -- memory address low  byte

   i2c_restart()
   r = r & i2c_transmit_byte(0xA1) -- i2c address for read (of memory from eeprom)

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(true)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte(false)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop()

   -- write part (relies on var i, we just read!)
   i2c_start()
   r =     i2c_transmit_byte(0xA0) -- i2c address for write (for memory address, within eeprom)
   r = r & i2c_transmit_byte(0x00) -- memory address high byte
   r = r & i2c_transmit_byte(0x02) -- memory address low  byte
   r = r & i2c_transmit_byte(i+1)  -- data byte
   i2c_stop()

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: i2c_hardware.jal


i2c_transmit_byte2 - JALlib Procedures Help

i2c_transmit_byte2 JALLIB FUNCTION

Signature

function i2c_transmit_byte2(byte in data) return bit is

Description

Returns TRUE when OK and FALSE in case of an error or when a timeout occurs
(if defined)

Include

To use this procedure, include the library:

include i2c_hardware2

Parameters

  • data - byte in

Return Value

bit - Function return value

Example

From sample file: 16f18325_i2c_hw2_l0.jal

-- ----------------------------------------------------------------------------
-- Title: Sample program for i2c_hardware2.jal.
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Level 0 i2c test program. Interact with a 24lc256 i2c eeprom using
--              the i2c primitives and i2c hardware 2.
--
-- Sources: Based on the sample program of Joep Suijs.
--
--
include 16f18325                    -- target PICmicro
--
-- This program uses the internal oscillator at 16 MHz.
pragma target clock   16_000_000    -- oscillator frequency
pragma target OSC      OFF          -- internal oscillator
pragma target RSTOSC   HFINT32      -- select 32 MHz
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

OSCCON1_NDIV = 0b0001               -- Fosc 16 MHz

enable_digital_io()                 -- Don't forget this otherwise I2C will not work.

-- Assign the pins. This must always be done to let it work even for
-- the default pin assignment.
include pps
pps_control_lock(FALSE)
-- USART pin assignment changed as to use the default for I2C 2.
RC2PPS = PPS_TX   -- USART transmit
RXPPS  = PPS_RC3  -- USART receive
-- I2C 2 bi-direactional pin assignments (default).
RC4PPS = PPS_SCK2     -- Output I2C 2 clock for EEPROM
RC5PPS = PPS_SDA2     -- Output I2C 2 data for EEPROM
SSP2CLKPPS  = PPS_RC4 -- Input  I2C 2 clock for EEPROM
SSP2DATPPS  = PPS_RC5 -- Input  I2C 2 data for EEPROM
pps_control_lock(TRUE)

-- I2C IO definition, using I2C hardware 2.
alias i2c_scl2_direction is pin_c4_direction -- pin 6 for 14 pin DIP.
alias i2c_sda2_direction is pin_c5_direction -- pin 5 for 14 pin DIP.

-- USART setup.
alias pin_RX_direction is pin_C3_direction -- Pin 7 of 14 pin DIP.
alias pin_TX_direction is pin_C2_direction -- Pin 8 of 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- EEPROM address. Change when needed.
const byte EEPROM_DEVICE_ADDRESS = 0xAE

include i2c_hardware2
i2c_initialize2()

-- we're alive
print_string(serial_hw_data, "Test.\r\n")

var bit r
var byte i

forever loop

   -- read first 3 bytes from an 24lc256 eeprom and output these to the serial port
   -- then, increment the last one (write one byte).
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r = i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x00) -- memory address low  byte

   i2c_restart2()
   -- i2c address for read (of memory from eeprom)
   r = r & i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS | 0x01)

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(TRUE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i = i2c_receive_byte2(FALSE)
   print_byte_hex(serial_hw_data, i);
   serial_hw_data = " "

   i2c_stop2()

   -- write part (relies on var i, we just read!)
   i2c_start2()
   -- i2c address for write (for memory address, within eeprom)
   r =     i2c_transmit_byte2(EEPROM_DEVICE_ADDRESS)
   r = r & i2c_transmit_byte2(0x00) -- memory address high byte
   r = r & i2c_transmit_byte2(0x02) -- memory address low  byte
   -- Only change the third position.
   r = r & i2c_transmit_byte2(i+1)  -- data byte
   i2c_stop2()

   print_crlf(serial_hw_data)

   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: i2c_hardware2.jal


icmp.jal - JALLIB Library Documentation

icmp.jal JALLIB LIBRARY

Title

Internet control message protocol (ICMP) BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Sends, receives and replys to icmp ECHO (PING) messages

Notes

ICMP message types

Sources

http://www.faqs.org/rfcs/rfc792.html
http://www.visualland.net/view.php?cid=857&protocol=ARP&title=1.%20Basic-update

Constants and Variables

ICMP_TYPE - const byte = 0
ICMP_CODE - const byte = 1
ICMP_CHECKSUM - const word = 2
ICMP_IDENTIFIER - const word = 4
ICMP_SEQUENCE_NUMBER - const word = 6
ECHO_HEADER_LENGTH - const byte = 8

Routines

  • icmp_read_packet - Procedure
  • icmp_send_echo - Procedure
  • icmp_send_echo_reply - Procedure


icmp_send_echo - JALlib Procedures Help

icmp_send_echo JALLIB PROCEDURE

Signature

procedure icmp_send_echo() is

Description

Sends an echo (PING) message

Include

To use this procedure, include the library:

include icmp

Parameters

None

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: icmp.jal


IF - JAL Language Syntax Reference

IF JALV2 SYNTAX

Syntax

IF lexpr THEN
    statement_block
    [ ELSIF lexpr THEN
        statement_block
      ... ]
    [ ELSE
        statement_block ]
END IF

Description

statement_block [ ELSIF lexpr 2 THEN statement_block ] [ ELSE statement_block ] END IF This creates a test, or series of tests. The statement_block under the ﬁrst lexpr that evaluates to 1 will be executed. Any number of ELSIF clauses are allowed. If no lexpr evaluates to true and the ELSE clause exists, the statement_block for the ELSE clause will be executed. A special case of the IF statement is when any lexpr is a constant 0. In this case, the statement block is not parsed. This can be used for block comments. IF 0 this is a dummy block that won’t even be parsed! END IF

Example

IF x == 5 THEN
y = 7
ELSIF x == 6 THEN
y = 12
ELSE
y = 0
END IF
17

Generated by JAL Syntax Documentation System | Source: DITA


ili9341_display_inverse - JALlib Procedures Help

ili9341_display_inverse JALLIB PROCEDURE

Signature

procedure ili9341_display_inverse() is

Description

Put the display in inverse mode.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_display_normal - JALlib Procedures Help

ili9341_display_normal JALLIB PROCEDURE

Signature

procedure ili9341_display_normal() is

Description

Put the display in normal (non-inverse) mode.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_display_off - JALlib Procedures Help

ili9341_display_off JALLIB PROCEDURE

Signature

procedure ili9341_display_off() is

Description

Turn the display off.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_display_on - JALlib Procedures Help

ili9341_display_on JALLIB PROCEDURE

Signature

procedure ili9341_display_on() is

Description

Turn the display on.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_display_sleep - JALlib Procedures Help

ili9341_display_sleep JALLIB PROCEDURE

Signature

procedure ili9341_display_sleep() is

Description

Turn the display into sleep mode.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_display_wakeup - JALlib Procedures Help

ili9341_display_wakeup JALLIB PROCEDURE

Signature

procedure ili9341_display_wakeup() is

Description

Wakeup the display from sleep mode.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_draw_image - JALlib Procedures Help

ili9341_draw_image JALLIB PROCEDURE

Signature

procedure ili9341_draw_image(word in image[],

Description

Draw an bitmap image from a byte array given in format Width * Height.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341_fat32_sd_card.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo showing showing pictures from an SD card on the ILI9341
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to show pictures on the ILI9341 which
--              are stored on an SD Card with a FAT32 file system. By pressing
--              the file number on the keyboard the image will be copied from the
--              SD card to the ILI9341 display.
--
--              Pictures stored must be in .bmp format using RGB 5-6-5 format.
--              You can find samples of bmp images in the project folder under:
--              jallib/project/ili9341.
--
-- Sources:     This sample program is based on the FAT32 SD Card sample program of
--              Matthew Schinkel.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- Also map pins for serial hardware.
-- Do not map the pins if ILI9341_SPI_SW is used.
-- -----------------------------------------------------------------
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341 and SD card.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Serial pins.
RC6PPS = PPS_TX   -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7  -- C7 re-assigned to RX1  (default)
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Setup the sd card pins.
alias sd_chip_select is pin_b1
alias sd_chip_select_direction is pin_b1_direction -- Pin 22 of 28 pin DIP.
sd_chip_select = high
sd_chip_select_direction = output
alias pin_sck is pin_c3 -- PIC SCK to SD_SCK
alias pin_sdo is pin_c4 -- PIC SDO to SD_MOSI
alias pin_sdi is pin_c5 -- PIC SDI to SD_MISO

-- Setup SPI library.
include spi_master_hw
-- init spi, choose mode and speed. SD card uses mode 11.
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4)
-- Interface aliases for sd card.
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange
alias spi_master_set_mode is spi_master_hw_set_mode
alias spi_master_set_speed is spi_master_hw_set_speed
-- Interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- -----------------------------------------------------------------
-- Most of the rest of this program comes from the fat32_sd_card
-- sample program of Matthew Schinkel with some modifications for
-- this PIC and leaving out parts that are not needed.
-- -----------------------------------------------------------------
-- Setup uart for communication
alias pin_RX_direction is pin_C7_direction -- Pin 18
alias pin_TX_direction is pin_C6_direction -- Pin 17
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
include delay

-- Include and initialize the GLCD lib. Clear the screen.
include glcd_ili9341
ili9341_init()
ili9341_fill_screen(ILI9341_GREEN)

-- Show that we are starting up.
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- Setup the sd card library.
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_DELAY_AFTER_WRITE = TRUE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- Setup fat32. Change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- Support writing of long file names.
const word FAT32_FILES_MAX = 20               -- The max number of files allowed in a directory.
const byte FAT32_FILE_NAME_SIZE = 80          -- Choose max file_name size. If a file_name is longer the this,
                                              -- beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5        -- Uses 6 bytes memory per fragment allowed (0 not allowed).
                                              -- Windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5       -- Uses 8 bytes memory per fragment allowed (0 not allowed).

-- Experts may change the following values.
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535

-- Setup a large array for storing sector data, This is where file_name locations are stored.
const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
include large_array_2                    -- include the array library
alias fat32_entry_location is large_array_2
include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT.
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"
if fat32_init_ok == TRUE then
   print_string(serial_data,"FAT32 READY!!!")
else
    print_string(serial_data,"FAT32 FAILED!!!")
end if
print_crlf(serial_data)

-- Procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Use a temporary buffer, size must be <= bytes 80 for
-- PIC14(H) and use a value that fits in 512 bytes.
const IMAGE_BUFFER_SIZE = 32 -- In words so 64 bytes.

-- Variables.
var dword image_size, image_size_counter, data_location, data_counter
var word data
var byte data_low at data
var byte data_high at data+1
var byte index
var dword step1
var word step2, x_coord, y_coord, width, height, odd_even
var word image_buffer[IMAGE_BUFFER_SIZE]
var byte file_number2 = 0

-- Main program starts here.

-- If you want to test the display rotation feature, add this:
-- ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)

forever loop

   separator()
   ------------------------------------------------------------
   -- list a directory, send it via serial port
   ------------------------------------------------------------
   fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   separator()

   print_crlf(serial_data)
   print_string(serial_data, "Press the file number on the keyboard to start.\r\n")
   -- Serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
      -- Indicate that there is any activity.
      print_string(serial_data, "Opening file ...\r\n")
      glcd_clear_screen()
   end if
   -- Read character. We get ASCII from the keyboard so make it binary.
   file_number2 = serial_data - "0"

   -- Choose a file for reading or dir for opening.
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      print_string(serial_data, "File is open.\r\n")
      -- Calculate number of sectors in file.
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

      -- Read from any sector number in the file
      data_counter = 0
      for sectors_available using step1 loop
         -- Read one sector from the disk.
         fat32_read_file_sector_number(step1)
         -- Read all data from one sector.
         step2 = 0
         while (step2 < 512) loop
            -- See if we need to get some BMP specific info.
            if (data_counter == 0x0A) then
               -- Get the location of the data, 4 bytes.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_location = dword(data)
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_location = data_location | (dword(data) << 16)
               data_counter = data_counter + 4
               print_string(serial_data, "Data is located at: ")
               print_dword_hex(serial_data, data_location)
               print_crlf(serial_data)
            elsif (data_counter == 0x12) then
               -- Get the width. Left to right order.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               width = data
               -- Skip the other two bytes.
               step2 = step2 + 2
               -- Another calculation is used when nr of pixels > 255.
               if (width > 255) then
                  width = (0xFFFF - width) + 1
               end if
               -- Get the height.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               height = data
               -- Skip the other two bytes.
               step2 = step2 + 2
               -- Another calculation is used when nr of pixels > 255.
               if (height > 255) then
                  height = (0xFFFF - height) + 1
               end if
               image_size = dword(width) * dword(height)
               data_counter = data_counter + 8
               print_string(serial_data, "Image width is: ")
               print_word_dec(serial_data, width)
               serial_data = " "
               print_string(serial_data, "Image height is: ")
               print_word_dec(serial_data, height)
               serial_data = " "
               print_string(serial_data, "Image size is: ")
               print_dword_dec(serial_data, image_size)
               print_crlf(serial_data)
               -- Reset some values for the next phase.
               x_coord = 0
               y_coord = 0
               index = 0
               image_size_counter = 0
               -- We have to do a correction when the width is odd.
               if (width % 2) > 0 then
                  odd_even = 1
               else
                  odd_even = 0
               end if
            elsif (data_counter >= data_location) &
                  (image_size_counter < image_size) then
               -- Data reception. Send it to the display.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               -- Fill the image buffer and send it to the display when full.
               image_buffer[index] = data
               image_size_counter = image_size_counter + 1
               index = index + 1
               -- If we are done for the width or buffer full, send it.
               if (index == IMAGE_BUFFER_SIZE) then
                  -- Buffer full, send to display and adjust coordinates.
                  ili9341_draw_image(image_buffer, x_coord, y_coord,
                                     index, 1)
                  index = 0
                  x_coord = x_coord + IMAGE_BUFFER_SIZE
               elsif ((word(index) + x_coord) == (width + odd_even)) then
                  -- Bufer not full but width reached.
                  ili9341_draw_image(image_buffer, x_coord, y_coord,
                                     index, 1)
                  index = 0
                  x_coord = 0
                  y_coord = y_coord + 1
              end if
            else
               -- Next.
               data_counter = data_counter + 1
               step2 = step2 + 1
            end if
         end loop
      end loop
      fat32_file_close()
      print_string(serial_data, "Done!\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_fill_screen - JALlib Procedures Help

ili9341_fill_screen JALLIB PROCEDURE

Signature

procedure ili9341_fill_screen(word in color) is

Description

Fill the screen with the given color. Color must be in RGB 5-6-5 format.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

  • color - word in

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341_fat32_sd_card.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo showing showing pictures from an SD card on the ILI9341
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to show pictures on the ILI9341 which
--              are stored on an SD Card with a FAT32 file system. By pressing
--              the file number on the keyboard the image will be copied from the
--              SD card to the ILI9341 display.
--
--              Pictures stored must be in .bmp format using RGB 5-6-5 format.
--              You can find samples of bmp images in the project folder under:
--              jallib/project/ili9341.
--
-- Sources:     This sample program is based on the FAT32 SD Card sample program of
--              Matthew Schinkel.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- Also map pins for serial hardware.
-- Do not map the pins if ILI9341_SPI_SW is used.
-- -----------------------------------------------------------------
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341 and SD card.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Serial pins.
RC6PPS = PPS_TX   -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7  -- C7 re-assigned to RX1  (default)
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Setup the sd card pins.
alias sd_chip_select is pin_b1
alias sd_chip_select_direction is pin_b1_direction -- Pin 22 of 28 pin DIP.
sd_chip_select = high
sd_chip_select_direction = output
alias pin_sck is pin_c3 -- PIC SCK to SD_SCK
alias pin_sdo is pin_c4 -- PIC SDO to SD_MOSI
alias pin_sdi is pin_c5 -- PIC SDI to SD_MISO

-- Setup SPI library.
include spi_master_hw
-- init spi, choose mode and speed. SD card uses mode 11.
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4)
-- Interface aliases for sd card.
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange
alias spi_master_set_mode is spi_master_hw_set_mode
alias spi_master_set_speed is spi_master_hw_set_speed
-- Interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- -----------------------------------------------------------------
-- Most of the rest of this program comes from the fat32_sd_card
-- sample program of Matthew Schinkel with some modifications for
-- this PIC and leaving out parts that are not needed.
-- -----------------------------------------------------------------
-- Setup uart for communication
alias pin_RX_direction is pin_C7_direction -- Pin 18
alias pin_TX_direction is pin_C6_direction -- Pin 17
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
include delay

-- Include and initialize the GLCD lib. Clear the screen.
include glcd_ili9341
ili9341_init()
ili9341_fill_screen(ILI9341_GREEN)

-- Show that we are starting up.
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- Setup the sd card library.
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_DELAY_AFTER_WRITE = TRUE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- Setup fat32. Change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- Support writing of long file names.
const word FAT32_FILES_MAX = 20               -- The max number of files allowed in a directory.
const byte FAT32_FILE_NAME_SIZE = 80          -- Choose max file_name size. If a file_name is longer the this,
                                              -- beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5        -- Uses 6 bytes memory per fragment allowed (0 not allowed).
                                              -- Windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5       -- Uses 8 bytes memory per fragment allowed (0 not allowed).

-- Experts may change the following values.
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535

-- Setup a large array for storing sector data, This is where file_name locations are stored.
const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
include large_array_2                    -- include the array library
alias fat32_entry_location is large_array_2
include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT.
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"
if fat32_init_ok == TRUE then
   print_string(serial_data,"FAT32 READY!!!")
else
    print_string(serial_data,"FAT32 FAILED!!!")
end if
print_crlf(serial_data)

-- Procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Use a temporary buffer, size must be <= bytes 80 for
-- PIC14(H) and use a value that fits in 512 bytes.
const IMAGE_BUFFER_SIZE = 32 -- In words so 64 bytes.

-- Variables.
var dword image_size, image_size_counter, data_location, data_counter
var word data
var byte data_low at data
var byte data_high at data+1
var byte index
var dword step1
var word step2, x_coord, y_coord, width, height, odd_even
var word image_buffer[IMAGE_BUFFER_SIZE]
var byte file_number2 = 0

-- Main program starts here.

-- If you want to test the display rotation feature, add this:
-- ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)

forever loop

   separator()
   ------------------------------------------------------------
   -- list a directory, send it via serial port
   ------------------------------------------------------------
   fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   separator()

   print_crlf(serial_data)
   print_string(serial_data, "Press the file number on the keyboard to start.\r\n")
   -- Serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
      -- Indicate that there is any activity.
      print_string(serial_data, "Opening file ...\r\n")
      glcd_clear_screen()
   end if
   -- Read character. We get ASCII from the keyboard so make it binary.
   file_number2 = serial_data - "0"

   -- Choose a file for reading or dir for opening.
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      print_string(serial_data, "File is open.\r\n")
      -- Calculate number of sectors in file.
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

      -- Read from any sector number in the file
      data_counter = 0
      for sectors_available using step1 loop
         -- Read one sector from the disk.
         fat32_read_file_sector_number(step1)
         -- Read all data from one sector.
         step2 = 0
         while (step2 < 512) loop
            -- See if we need to get some BMP specific info.
            if (data_counter == 0x0A) then
               -- Get the location of the data, 4 bytes.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_location = dword(data)
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_location = data_location | (dword(data) << 16)
               data_counter = data_counter + 4
               print_string(serial_data, "Data is located at: ")
               print_dword_hex(serial_data, data_location)
               print_crlf(serial_data)
            elsif (data_counter == 0x12) then
               -- Get the width. Left to right order.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               width = data
               -- Skip the other two bytes.
               step2 = step2 + 2
               -- Another calculation is used when nr of pixels > 255.
               if (width > 255) then
                  width = (0xFFFF - width) + 1
               end if
               -- Get the height.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               height = data
               -- Skip the other two bytes.
               step2 = step2 + 2
               -- Another calculation is used when nr of pixels > 255.
               if (height > 255) then
                  height = (0xFFFF - height) + 1
               end if
               image_size = dword(width) * dword(height)
               data_counter = data_counter + 8
               print_string(serial_data, "Image width is: ")
               print_word_dec(serial_data, width)
               serial_data = " "
               print_string(serial_data, "Image height is: ")
               print_word_dec(serial_data, height)
               serial_data = " "
               print_string(serial_data, "Image size is: ")
               print_dword_dec(serial_data, image_size)
               print_crlf(serial_data)
               -- Reset some values for the next phase.
               x_coord = 0
               y_coord = 0
               index = 0
               image_size_counter = 0
               -- We have to do a correction when the width is odd.
               if (width % 2) > 0 then
                  odd_even = 1
               else
                  odd_even = 0
               end if
            elsif (data_counter >= data_location) &
                  (image_size_counter < image_size) then
               -- Data reception. Send it to the display.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               -- Fill the image buffer and send it to the display when full.
               image_buffer[index] = data
               image_size_counter = image_size_counter + 1
               index = index + 1
               -- If we are done for the width or buffer full, send it.
               if (index == IMAGE_BUFFER_SIZE) then
                  -- Buffer full, send to display and adjust coordinates.
                  ili9341_draw_image(image_buffer, x_coord, y_coord,
                                     index, 1)
                  index = 0
                  x_coord = x_coord + IMAGE_BUFFER_SIZE
               elsif ((word(index) + x_coord) == (width + odd_even)) then
                  -- Bufer not full but width reached.
                  ili9341_draw_image(image_buffer, x_coord, y_coord,
                                     index, 1)
                  index = 0
                  x_coord = 0
                  y_coord = y_coord + 1
              end if
            else
               -- Next.
               data_counter = data_counter + 1
               step2 = step2 + 1
            end if
         end loop
      end loop
      fat32_file_close()
      print_string(serial_data, "Done!\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_goto - JALlib Procedures Help

ili9341_goto JALLIB PROCEDURE

Signature

procedure ili9341_goto(word in x, word in y) is

Description

Set the current position in pixels for the data to be written. Used for
writing characters to the screen. Character are written as bitmap so x
and y must be given as pixel locations.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

  • x - word in
  • y - word in

Return Value

None

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_init - JALlib Procedures Help

ili9341_init JALLIB PROCEDURE

Signature

procedure ili9341_init() is

Description

Initialize the control pins, the SPI interface and the initialize the
ILI9341 module. When the reset hardware pin is defined then the module will
be hardware reset, otherwise it will be software reset.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_touch_interrupt_ads7843.jal

-- -----------------------------------------------------------------------------
-- Title: Sample showing the operation of the touch screen on an ili9341.
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing the operation of the touch screen on an
--              ILI9341 TFT full color display based on an ads7843/XPT2406 touch
--              screen IC. It shows how the interrupt of the ads7843 can be used.
--              When the screen is touched, the x and y coordinates of the touch
--              location will be shown on the display for half a second.
--
-- Notes:       The interrupt output of the touch screen is open drain so it
--              must be connected to VCC via a 10 kOhm resistor.
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 32 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Map the interrupt pin to pin A5. Note: The datasheet is not very clear
-- on this so the hard coded number of pin A5 (0x05) is used here.
INTPPS = 0x05 -- Interrupt pin on A5.
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. When needed use these settings:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- Now specify SPI pins aliases for the touch screen. It uses its own
-- software SPI since it clocks data on different edges.
alias ads7843_csn is pin_b5 -- Pin 28 (T_CS)
alias ads7843_csn_direction is pin_b5_direction
ads7843_csn = HIGH -- Disable ads7843.
ads7843_csn_direction = output
alias ads7843_sck is pin_b4  -- Pin 27 (T_CLK)
alias ads7843_sck_direction is pin_b4_direction
ads7843_sck_direction = output
alias ads7843_sdi is pin_b3  -- Pin 26 (T_DO)
alias ads7843_sdi_direction is pin_b3_direction
ads7843_sdi_direction = input
alias ads7843_sdo is pin_b2  -- Pin 25 (T_DIN)
alias ads7843_sdo_direction is pin_b2_direction
ads7843_sdo_direction = output

-- Set interrrupt pin, connected to A5, to input.
pin_a5_direction = input

-- Some other used libraries.
include print
include delay

-- Font library.
include glcd_12x16_font

-- Include the graphics library and initialize.
include glcd_ili9341
ili9341_init()

-- Include the touch library and initialize.
include glcd_touch_ads7843
ads7843_init()

-- Variables.
var word touch_x, touch_y, pixel_x, pixel_y
var bit  new_touch_data

--  -------------------- Procedures and Functions -----------------------------

-- External interrupt procedure.
procedure external_interrupt() is pragma interrupt

   if PIR0_INTF then
      new_touch_data = TRUE
      PIR0_INTF = FALSE
   end if

end procedure

-- --------------- Variables and start of program ----------------------------

-- Initialize the external interrrupt. It is active low.
INTCON_INTEDG = FALSE -- React on falling edge
PIR0_INTF     = FALSE -- Clear interrupt flag
PIE0_INTE     = TRUE  -- Enable external interrupt
INTCON_GIE    = TRUE  -- Enable all interrupts
new_touch_data = FALSE

-- Main loop starts here. First write some text.
glcd_font_use(FONT_12X16)
glcd_clear_screen()
glcd_pen_color = ILI9341_MAGENTA
ili9341_goto(10,10)
print_string(glcd,"TOUCH ON INTERRUPT")
ili9341_goto(10,30)
print_string(glcd,"==================")

glcd_pen_color = ILI9341_YELLOW
ili9341_goto(5,100)
print_string(glcd,"TOUCH ME!")
ili9341_goto(5,120)
print_string(glcd,"---------")

glcd_pen_color = ILI9341_GREEN
ili9341_goto(5,150)
print_string(glcd,"Touched at X : ")
ili9341_goto(5,180)
print_string(glcd,"Touched at Y : ")

forever  loop

   if new_touch_data then
      -- Get the coordinates and write them to the screen.
      if ads7843_get_touch_coordinate(touch_x, touch_y) then
         -- Valid coordinates, translate to pixel coordinates.
         ads7843_touch_to_display_coordinate(touch_x, touch_y, pixel_x, pixel_y)
         -- Now write them to the screen.
         ili9341_goto(180,150)
         print_word_dec(glcd, pixel_x)
         ili9341_goto(180,180)
         print_word_dec(glcd, pixel_y)
         _usec_delay(500_000)
      end if
      new_touch_data = FALSE
   else
      -- Erase the coordinates.
      ili9341_goto(180,150)
      print_string(glcd, "    ")
      ili9341_goto(180,180)
      print_string(glcd, "    ")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_mirror_x_off - JALlib Procedures Help

ili9341_mirror_x_off JALLIB PROCEDURE

Signature

procedure ili9341_mirror_x_off() is

Description

Reset mirroring the display in the x-direction.
Use ili9341_set_display_rotation() to activate.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_mirror_x_on - JALlib Procedures Help

ili9341_mirror_x_on JALLIB PROCEDURE

Signature

procedure ili9341_mirror_x_on() is

Description

Set mirroring the display in the x-direction.
Use ili9341_set_display_rotation() to activate.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_mirror_y_off - JALlib Procedures Help

ili9341_mirror_y_off JALLIB PROCEDURE

Signature

procedure ili9341_mirror_y_off() is

Description

Reset mirroring the display in the y-direction.
Use ili9341_set_display_rotation() to activate.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_mirror_y_on - JALlib Procedures Help

ili9341_mirror_y_on JALLIB PROCEDURE

Signature

procedure ili9341_mirror_y_on() is

Description

Set mirroring the display in the y-direction.
Use ili9341_set_display_rotation() to activate.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_set_display_rotation - JALlib Procedures Help

ili9341_set_display_rotation JALLIB PROCEDURE

Signature

procedure ili9341_set_display_rotation(byte in rotation) is

Description

Set display rotation to 0, 90, 180 or 270 degrees, see ILI9341_ROTATE.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

  • rotation - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341_fat32_sd_card.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo showing showing pictures from an SD card on the ILI9341
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to show pictures on the ILI9341 which
--              are stored on an SD Card with a FAT32 file system. By pressing
--              the file number on the keyboard the image will be copied from the
--              SD card to the ILI9341 display.
--
--              Pictures stored must be in .bmp format using RGB 5-6-5 format.
--              You can find samples of bmp images in the project folder under:
--              jallib/project/ili9341.
--
-- Sources:     This sample program is based on the FAT32 SD Card sample program of
--              Matthew Schinkel.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- Also map pins for serial hardware.
-- Do not map the pins if ILI9341_SPI_SW is used.
-- -----------------------------------------------------------------
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341 and SD card.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
-- Serial pins.
RC6PPS = PPS_TX   -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7  -- C7 re-assigned to RX1  (default)
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Setup the sd card pins.
alias sd_chip_select is pin_b1
alias sd_chip_select_direction is pin_b1_direction -- Pin 22 of 28 pin DIP.
sd_chip_select = high
sd_chip_select_direction = output
alias pin_sck is pin_c3 -- PIC SCK to SD_SCK
alias pin_sdo is pin_c4 -- PIC SDO to SD_MOSI
alias pin_sdi is pin_c5 -- PIC SDI to SD_MISO

-- Setup SPI library.
include spi_master_hw
-- init spi, choose mode and speed. SD card uses mode 11.
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4)
-- Interface aliases for sd card.
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange
alias spi_master_set_mode is spi_master_hw_set_mode
alias spi_master_set_speed is spi_master_hw_set_speed
-- Interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- -----------------------------------------------------------------
-- Most of the rest of this program comes from the fat32_sd_card
-- sample program of Matthew Schinkel with some modifications for
-- this PIC and leaving out parts that are not needed.
-- -----------------------------------------------------------------
-- Setup uart for communication
alias pin_RX_direction is pin_C7_direction -- Pin 18
alias pin_TX_direction is pin_C6_direction -- Pin 17
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
include delay

-- Include and initialize the GLCD lib. Clear the screen.
include glcd_ili9341
ili9341_init()
ili9341_fill_screen(ILI9341_GREEN)

-- Show that we are starting up.
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- Setup the sd card library.
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_DELAY_AFTER_WRITE = TRUE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

-- Setup fat32. Change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- Support writing of long file names.
const word FAT32_FILES_MAX = 20               -- The max number of files allowed in a directory.
const byte FAT32_FILE_NAME_SIZE = 80          -- Choose max file_name size. If a file_name is longer the this,
                                              -- beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5        -- Uses 6 bytes memory per fragment allowed (0 not allowed).
                                              -- Windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5       -- Uses 8 bytes memory per fragment allowed (0 not allowed).

-- Experts may change the following values.
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535

-- Setup a large array for storing sector data, This is where file_name locations are stored.
const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
include large_array_2                    -- include the array library
alias fat32_entry_location is large_array_2
include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT.
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"
if fat32_init_ok == TRUE then
   print_string(serial_data,"FAT32 READY!!!")
else
    print_string(serial_data,"FAT32 FAILED!!!")
end if
print_crlf(serial_data)

-- Procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Use a temporary buffer, size must be <= bytes 80 for
-- PIC14(H) and use a value that fits in 512 bytes.
const IMAGE_BUFFER_SIZE = 32 -- In words so 64 bytes.

-- Variables.
var dword image_size, image_size_counter, data_location, data_counter
var word data
var byte data_low at data
var byte data_high at data+1
var byte index
var dword step1
var word step2, x_coord, y_coord, width, height, odd_even
var word image_buffer[IMAGE_BUFFER_SIZE]
var byte file_number2 = 0

-- Main program starts here.

-- If you want to test the display rotation feature, add this:
-- ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)

forever loop

   separator()
   ------------------------------------------------------------
   -- list a directory, send it via serial port
   ------------------------------------------------------------
   fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   separator()

   print_crlf(serial_data)
   print_string(serial_data, "Press the file number on the keyboard to start.\r\n")
   -- Serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
      -- Indicate that there is any activity.
      print_string(serial_data, "Opening file ...\r\n")
      glcd_clear_screen()
   end if
   -- Read character. We get ASCII from the keyboard so make it binary.
   file_number2 = serial_data - "0"

   -- Choose a file for reading or dir for opening.
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      print_string(serial_data, "File is open.\r\n")
      -- Calculate number of sectors in file.
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

      -- Read from any sector number in the file
      data_counter = 0
      for sectors_available using step1 loop
         -- Read one sector from the disk.
         fat32_read_file_sector_number(step1)
         -- Read all data from one sector.
         step2 = 0
         while (step2 < 512) loop
            -- See if we need to get some BMP specific info.
            if (data_counter == 0x0A) then
               -- Get the location of the data, 4 bytes.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_location = dword(data)
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_location = data_location | (dword(data) << 16)
               data_counter = data_counter + 4
               print_string(serial_data, "Data is located at: ")
               print_dword_hex(serial_data, data_location)
               print_crlf(serial_data)
            elsif (data_counter == 0x12) then
               -- Get the width. Left to right order.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               width = data
               -- Skip the other two bytes.
               step2 = step2 + 2
               -- Another calculation is used when nr of pixels > 255.
               if (width > 255) then
                  width = (0xFFFF - width) + 1
               end if
               -- Get the height.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               height = data
               -- Skip the other two bytes.
               step2 = step2 + 2
               -- Another calculation is used when nr of pixels > 255.
               if (height > 255) then
                  height = (0xFFFF - height) + 1
               end if
               image_size = dword(width) * dword(height)
               data_counter = data_counter + 8
               print_string(serial_data, "Image width is: ")
               print_word_dec(serial_data, width)
               serial_data = " "
               print_string(serial_data, "Image height is: ")
               print_word_dec(serial_data, height)
               serial_data = " "
               print_string(serial_data, "Image size is: ")
               print_dword_dec(serial_data, image_size)
               print_crlf(serial_data)
               -- Reset some values for the next phase.
               x_coord = 0
               y_coord = 0
               index = 0
               image_size_counter = 0
               -- We have to do a correction when the width is odd.
               if (width % 2) > 0 then
                  odd_even = 1
               else
                  odd_even = 0
               end if
            elsif (data_counter >= data_location) &
                  (image_size_counter < image_size) then
               -- Data reception. Send it to the display.
               data_low = fat32_sector_buffer[step2]
               step2 = step2 + 1
               data_high = fat32_sector_buffer[step2]
               step2 = step2 + 1
               -- Fill the image buffer and send it to the display when full.
               image_buffer[index] = data
               image_size_counter = image_size_counter + 1
               index = index + 1
               -- If we are done for the width or buffer full, send it.
               if (index == IMAGE_BUFFER_SIZE) then
                  -- Buffer full, send to display and adjust coordinates.
                  ili9341_draw_image(image_buffer, x_coord, y_coord,
                                     index, 1)
                  index = 0
                  x_coord = x_coord + IMAGE_BUFFER_SIZE
               elsif ((word(index) + x_coord) == (width + odd_even)) then
                  -- Bufer not full but width reached.
                  ili9341_draw_image(image_buffer, x_coord, y_coord,
                                     index, 1)
                  index = 0
                  x_coord = 0
                  y_coord = y_coord + 1
              end if
            else
               -- Next.
               data_counter = data_counter + 1
               step2 = step2 + 1
            end if
         end loop
      end loop
      fat32_file_close()
      print_string(serial_data, "Done!\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_set_vertical_scroll_area - JALlib Procedures Help

ili9341_set_vertical_scroll_area JALLIB PROCEDURE

Signature

procedure ili9341_set_vertical_scroll_area(word in top, word in bottom) is

Description

Set the scroll area of the display. top is the height of the top scroll
margin and bottom the height of the bottom margin.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

  • top - word in
  • bottom - word in

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ili9341_vertical_scroll_display - JALlib Procedures Help

ili9341_vertical_scroll_display JALLIB PROCEDURE

Signature

procedure ili9341_vertical_scroll_display(word in number_of_pixels) is

Description

Scroll the display vertical with the given numer of pixels.

Include

To use this procedure, include the library:

include glcd_ili9341

Parameters

  • number_of_pixels - word in

Return Value

None

Example

From sample file: 16f18857_glcd_ili9341.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD ILI9341 demo sample showing text (fonts) and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2022..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD ILI9341. It demonstrates
--              all features of the glcd_ili9341.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images.
--
--              You can find the file jal_logo.jal in the project folder
--              jallib/project/ili9341. Copy this file to your local folder.
--
-- Notes:       A way to generate the bitmap from a png or jpg file:
--              Converter: https://online-converting.com/image/convert2bmp/
--              Choose: 16 (5:6:5 RGB Hi-Color), rows direction Top - Bottom
--

include 16f18857
-- When using a crytal of 20 MHz
-- pragma target clock 20_000_000      -- oscillator frequency
-- pragma target OSC      HS           -- crystal or resonator
-- pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
-- pragma target CLKOUTEN DISABLED     -- no clock output
-- pragma target WDT      DISABLED     -- watchdog
-- pragma target BROWNOUT DISABLED     -- no brownout reset
-- pragma target FCMEN    DISABLED     -- no clock monitoring
-- pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
-- pragma target LVP      ENABLED      -- use low voltage programming
-- pragma target MCLR     EXTERNAL     -- external reset

-- When using internal oscillator at 16 MHz (PIC running at 3.3 Volt).
pragma target clock    16_000_000       -- oscillator frequency
pragma target OSC      OFF              -- internal oscillator
pragma target RSTOSC   HFINT32          -- select 32 MHz
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target CSWEN    ENABLED          -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCFRQ_HFFRQ = 0b101                    -- Fosc 16 MHz

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- Set the pinning for the hardware pins of SPI. This is default but still
-- needed for this chip. Do not use this when using software SPI since the
-- pins are then assigned for hardware SPI.
include pps
pps_control_lock(FALSE)
-- SPI 1 used by ili9341.
RC3PPS = PPS_SCK1 -- SPI clock
RC4PPS = PPS_SDA1 -- SPI data in
RC5PPS = PPS_SDO1 -- SPI data out
pps_control_lock(TRUE)

-- Define the SPI pins and other used pins to control the display and
-- initiaize the pin direction.
alias ili9341_sck is pin_C3   -- PIC SCK to pin 7 of the module (SCK).
alias ili9341_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP.
ili9341_sck_direction = output
alias ili9341_sdi is pin_C4   -- PIC SDI to pin 9 of the module (SDO - MISO).
alias ili9341_sdi_direction is pin_C4_direction -- Pin 15 of 28 pin DIP.
ili9341_sdi_direction = input
alias ili9341_sdo is pin_C5   -- PIC SDO to pin 6 of the module (SDI - MOSI).
alias ili9341_sdo_direction is pin_C5_direction -- Pin 16 of 28 pin DIP.
ili9341_sdo_direction = output
-- Extra needed for SPI.
alias ili9341_csn is pin_C2   -- PIC CS to pin 3 of the module (CS).
alias ili9341_csn_direction is pin_C2_direction  -- Pin 13 of 28 pin DIP.
ili9341_csn = high
ili9341_csn_direction = output
alias ili9341_dc_rs is pin_C1 -- PIC DC/RS to pin 5 of the module (DC/RS).
alias ili9341_dc_rs_direction is pin_C1_direction -- Pin 12 of 28 pin DIP.
ili9341_dc_rs_direction = output
-- Optional hardware reset pin. If not defined, software reset will be used.
alias ili9341_rst is pin_C0   -- PIC RES to pin 4 of the module (RESET).
alias ili9341_rst_direction is pin_C0_direction  -- Pin 11 of 28 pin DIP.
ili9341_rst_direction = output

-- Now include the used SPI interface.
include spi_master_hw
-- Set SPI mode 00. When the target clock is > 50 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the ILI9341.
alias ili9341_spi_host is spi_master_hw

-- The default display resolution is 240 x 320 pixels If a display with a
-- different resolution is used you can overrule these as follows (example):
-- const word ILI9341_MAX_X_PIXELS = 128  -- Width
-- const word ILI9341_MAX_Y_PIXELS = 160  -- Height

-- Some displays require mirroring. For some display it is sufficient to
-- set this once which can be done using the folling constants:
-- const ILI9341_MIRROR_X = TRUE -- Will mirror in the x-direction
-- const ILI9341_MIRROR_Y = TRUE -- Will mirror in the y-direction

-- However, there are displays which require dynamic mirroring because they
-- are assembled in a different way. This can be done using the following
-- procedures: ili9341_mirror_x_on(), ili9341_mirror_x_off()
--             ili9341_mirror_y_on(), ili9341_mirror_y_off()
-- After calling one of these procedures you must call the procedure:
--             ili9341_set_display_rotation() to activate the mirroring.

procedure ili9341_mirror_x_on()

-- Some utility libraries.
include print
include delay
-- Font library.
include glcd_8x12_font

-- Include and initialize the GLCD lib.
include glcd_ili9341
ili9341_init()

-- This JAL image file and other JAL image files can be found
-- in jallib/project/ili9341. There is you also find a Python script
-- to create these JAL image files from .bmp files.
-- Since the JAL logo is not in the sample file it is initially not
-- included in this sample program
-- const WITH_JAL_LOGO = TRUE -- Remove the comments if you want to use the JAL logo

-- Include the JAL lofo.
if defined(WITH_JAL_LOGO) then
   include jal_logo
end if

-- Variables.
var byte counter, radius
var word x_coord, y_coord, scroll

forever  loop

   -- First write the demo text.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_font_use(FONT_8X12)
   ili9341_goto(80,100)
   print_string(glcd,"JAL ILI9341")
   ili9341_goto(80,120)
   glcd_pen_color = ILI9341_GREEN
   print_string(glcd,"Library Demo")
   ili9341_goto(80,140)
   glcd_pen_color = ILI9341_WHITE
   print_string(glcd,"2021-09-09")
   ili9341_goto(80,160)
   glcd_pen_color = ILI9341_YELLOW
   print_string(glcd,"Text only")
   ili9341_goto(80,180)
   glcd_pen_color = ILI9341_CYAN
   print_string(glcd,"Font 8X12")
   delay_1s(1)

   -- Show some display features.
   glcd_pen_color = ILI9341_WHITE
   ili9341_goto(70,220)
   print_string(glcd,"INVERSE DISPLAY")
   ili9341_display_inverse()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"NORMAL DISPLAY ")
   ili9341_display_normal()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY OFF    ")
   delay_1s(1)
   ili9341_display_off()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY ON     ")
   ili9341_display_on()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY SLEEP  ")
   delay_1s(1)
   ili9341_display_sleep()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"DISPLAY WAKEUP ")
   ili9341_display_wakeup()
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"VERTICAL SCROLL")
   ili9341_set_vertical_scroll_area(25, 25)
   for 100 using scroll loop
      ili9341_vertical_scroll_display(scroll)
      _usec_delay(10_000_)
   end loop
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"AREA RESET     ")
   ili9341_set_vertical_scroll_area(0, 0)
   delay_1s(3)
   ili9341_goto(70,220)
   print_string(glcd,"SCROLL RESET   ")
   -- Reset scroll
   ili9341_vertical_scroll_display(0)
   delay_1s(3)
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 0 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 90 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_180_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 180 DEGREES")
   delay_1s(1)
   ili9341_set_display_rotation(ILI9341_ROTATE_270_DEGREES)
   ili9341_goto(0,0)
   print_string(glcd,"DISPLAY ROTATION 270 DEGREES")
   delay_1s(3)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)

  -- Change the color of the screen a few times.
   glcd_clear_screen()
   delay_1s(1)
   ili9341_fill_screen(ILI9341_RED)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_GREEN)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_BLUE)
   delay_1s(1)
   ili9341_fill_screen(ILI9341_YELLOW)
   delay_1s(1)

   -- ------------------Do some graphics stuff ---------------------
   -- Draw some lines.
   -- From top left to bottom right.
   glcd_clear_screen()
   glcd_pen_color = ILI9341_RED
   glcd_line(0, 0, glcd_display_x_size - 1, glcd_display_y_size - 1)
   -- From top right to bottom left.
   glcd_pen_color = ILI9341_GREEN
   glcd_line(glcd_display_x_size - 1, 0, 0, glcd_display_y_size - 1)
   -- In the middle from left to right.
   glcd_pen_color = ILI9341_BLUE
   glcd_line(0, glcd_display_y_size / 2 , glcd_display_x_size - 1 , glcd_display_y_size / 2)
   -- In the middel from top to bottom
   glcd_pen_color = ILI9341_GREENYELLOW
   glcd_line(glcd_display_x_size / 2 , 0, glcd_display_x_size / 2, glcd_display_y_size - 1)
   delay_1s(3)

  -- Draw boxes on the screen.
   x_coord = 0
   y_coord = 0
   glcd_clear_screen()
   glcd_pen_color = ILI9341_GREEN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_box(x_coord, y_coord, glcd_display_x_size - x_coord , glcd_display_y_size - y_coord)
      x_coord = x_coord + 1
      y_coord = y_coord + 1
      -- Change color do that we can see the boxes.
      if (glcd_pen_color == ILI9341_GREEN) then
         glcd_pen_color = ILI9341_RED
      else
         glcd_pen_color = ILI9341_GREEN
      end if
   end loop
   delay_1s(3)

  -- Draw circels on the screen.
   radius = 1
   ili9341_fill_screen(ILI9341_GREENYELLOW)
   glcd_pen_color = ILI9341_MAGENTA
   while (radius < (glcd_display_x_size / 2)) loop
      glcd_circle(glcd_display_x_size / 2, glcd_display_y_size / 2, radius)
      radius = radius + 1
      -- Change color do that we can see the circles.
      if (glcd_pen_color == ILI9341_MAGENTA) then
         glcd_pen_color = ILI9341_MAROON
      else
         glcd_pen_color = ILI9341_MAGENTA
      end if
   end loop
   delay_1s(3)

  -- Draw elipses on a rotated screen.
   x_coord = 1
   y_coord = 1
   radius = 1
   ili9341_fill_screen(ILI9341_RED)
   -- Let's rotate the screen for this one.
   ili9341_set_display_rotation(ILI9341_ROTATE_90_DEGREES)
   glcd_pen_color = ILI9341_CYAN
   while (x_coord <= (glcd_display_x_size / 2)) loop
      glcd_ellipse(glcd_display_x_size / 2, glcd_display_y_size / 2, x_coord, y_coord)
      x_coord = x_coord + 1
      if (x_coord % 2) == 0 then
         y_coord = y_coord + 1
      end if
      -- Change color do that we can see the elipses.
      if (glcd_pen_color == ILI9341_CYAN) then
         glcd_pen_color = ILI9341_MAGENTA
      else
         glcd_pen_color = ILI9341_CYAN
      end if
   end loop
   delay_1s(3)

if defined(WITH_JAL_LOGO) then
   -- Draw an image. Note the screen is still rotated so the picture will
   -- also be rotated.
   glcd_clear_screen()
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 90, JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   -- Restore rotation.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
   -- Draw the same one on another location without rotation.
   ili9341_draw_image(JAL_LOGO_BITMAP, 60, 200,JAL_LOGO_WIDTH,
                      JAL_LOGO_HEIGHT)
   delay_1s(10)
else
   -- Restore rotation since picture is not shown but display is still rotated.
   ili9341_set_display_rotation(ILI9341_ROTATE_0_DEGREES)
end if

end loop

Generated by JALlib CHM Help System | Source: glcd_ili9341.jal


ina3221.jal - JALLIB Library Documentation

ina3221.jal JALLIB LIBRARY

Title

INA3221 Triple Channel Shunt and Bus Votage Monitor library.

Author

Rob Jansen, Copyright (c) 2025..2025, all rights reserved., Adapted-by:

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Libray for the INA3221 Triple-Channel, High-Side Measurement,
Shunt and Bus Voltage Monitor. It is controlled using the IIC
interface at a maximum speed of 400 kHz.
This library supports the use of word/dword for values or floats.
The default is the use of word/dword to reduce code size and
increase speed. In order to make use of floats define the
following before including this library:
-) Const INA3221_USE_FLOAT = TRUE
When using word/dword: When using float:
-) Shunt resistor is in mOhm -) Shunt resistor is in Ohm
-) Shunt voltage is in uV -) Shunt voltage in in Volt
-) Bus voltage in in mv -) Bus voltage is in Volt
-) Current is in uA -) Current in in Ampere

Notes

The main program must initialize the used - default - IIC interface
with a maximum speed of 400 kHz and with a I2C_HARDWARE_TIMEOUT
defined. Channels are numbered 1..3, but values 0..2 are used.
-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Default 7-bit IIC address of the ina3221 with A0 connected to GND.

Sources

Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
Measurement, Shunt and Bus Voltage Monitor with I2C- and
SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016

Constants and Variables

INA3221_IIC_DEFAULT_ADDRESS - const byte = 0x40
INA3221_NR_OF_CHANNELS - const byte = 3
INA3221_CHANNEL_1 - const byte = 0
INA3221_CHANNEL_2 - const byte = 1
INA3221_CHANNEL_3 - const byte = 2

Routines

  • _ina3221_read_data_word - Function returns word
  • _ina3221_write_data_word - Procedure
  • get_die_id - Function returns word
  • get_manufacturer_id - Function returns word
  • ina3221_conversion_ready - Function returns bit
  • ina3221_critical_alert - Function returns bit
  • ina3221_disable_channel - Procedure
  • ina3221_disable_critical_alert_latch - Procedure
  • ina3221_disable_summation_channel - Procedure
  • ina3221_disable_warning_alert_latch - Procedure
  • ina3221_enable_channel - Procedure
  • ina3221_enable_critical_alert_latch - Procedure
  • ina3221_enable_summation_channel - Procedure
  • ina3221_enable_warning_alert_latch - Procedure
  • ina3221_get_bus_voltage - Function returns float
  • ina3221_get_bus_voltage - Function returns word
  • ina3221_get_critical_alert_limit - Function returns float
  • ina3221_get_critical_alert_limit - Function returns sdword
  • ina3221_get_current - Function returns float
  • ina3221_get_current - Function returns sdword
  • ina3221_get_flags - Function returns word
  • ina3221_get_iic_address - Function returns byte
  • ina3221_get_power_valid_lower_limit - Function returns float
  • ina3221_get_power_valid_lower_limit - Function returns word
  • ina3221_get_power_valid_upper_limit - Function returns float
  • ina3221_get_power_valid_upper_limit - Function returns word
  • ina3221_get_register_value - Function returns word
  • ina3221_get_shunt_resistance - Function returns float
  • ina3221_get_shunt_resistance - Function returns dword
  • ina3221_get_shunt_voltage - Function returns float
  • ina3221_get_shunt_voltage - Function returns sdword
  • ina3221_get_warning_alert_limit - Function returns float
  • ina3221_get_warning_alert_limit - Function returns sdword
  • ina3221_init - Procedure
  • ina3221_power_valid_alert - Function returns bit
  • ina3221_reset - Procedure
  • ina3221_set_averaging_samples - Procedure
  • ina3221_set_bus_voltage_conversion_time - Procedure
  • ina3221_set_critical_alert_limit - Procedure
  • ina3221_set_critical_alert_limit - Procedure
  • ina3221_set_iic_address - Procedure
  • ina3221_set_operating_mode - Procedure
  • ina3221_set_power_valid_lower_limit - Procedure
  • ina3221_set_power_valid_lower_limit - Procedure
  • ina3221_set_power_valid_upper_limit - Procedure
  • ina3221_set_power_valid_upper_limit - Procedure
  • ina3221_set_shunt_resistance - Procedure
  • ina3221_set_shunt_resistance - Procedure
  • ina3221_set_shunt_voltage_conversion_time - Procedure
  • ina3221_set_warning_alert_limit - Procedure
  • ina3221_set_warning_alert_limit - Procedure
  • ina3221_summation_alert - Function returns bit
  • ina3221_timeout_occured - Function returns bit
  • ina3221_timing_control_alert - Function returns bit
  • ina3221_warning_alert - Function returns bit


ina3221_critical_alert - JALlib Procedures Help

ina3221_critical_alert JALLIB FUNCTION

Signature

function ina3221_critical_alert(word in flags, byte in channel) return bit is

Description

Returns TRUE if the critical alert for the given channel is active.
Channel in range 0..2. Channel must be active for the alert.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • flags - word in
  • channel - byte in

Return Value

bit - Function return value

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_get_bus_voltage - JALlib Procedures Help

ina3221_get_bus_voltage JALLIB FUNCTION

Signature

function ina3221_get_bus_voltage(byte in channel) return word is

Description

Get the bus voltage of the given channel in mV. Channel in range 0..2.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • channel - byte in

Return Value

word - Function return value

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_get_current - JALlib Procedures Help

ina3221_get_current JALLIB FUNCTION

Signature

function ina3221_get_current(byte in channel) return sdword is

Description

Get the current of the given channel in uA. Channel in range 0..2.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • channel - byte in

Return Value

None

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_get_flags - JALlib Procedures Help

ina3221_get_flags JALLIB FUNCTION

Signature

function ina3221_get_flags() return word is

Description

Get the flags from the mask/enable register. This call will clear the flags
if a condition is no longer active. For that reason reading the flags from
the mask enable/disable regsiter once makes it possible to check later
which alert flags are active.

Include

To use this procedure, include the library:

include ina3221

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_get_shunt_voltage - JALlib Procedures Help

ina3221_get_shunt_voltage JALLIB FUNCTION

Signature

function ina3221_get_shunt_voltage(byte in channel) return sdword is

Description

Get the shunt voltage of the given channel in uV. Channel in range 0..2.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • channel - byte in

Return Value

None

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_init - JALlib Procedures Help

ina3221_init JALLIB PROCEDURE

Signature

procedure ina3221_init() is

Description

Initialize the library. The shunt resistor is set to 0.1 Ohm.
The device is reset.

Include

To use this procedure, include the library:

include ina3221

Parameters

None

Return Value

None

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_set_critical_alert_limit - JALlib Procedures Help

ina3221_set_critical_alert_limit JALLIB PROCEDURE

Signature

procedure ina3221_set_critical_alert_limit(byte in channel, sdword in limit) is

Description

Set the critical alert limit of the shunt voltage for the given channel.
Channel in range 0..2. Limit is in uV.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • channel - byte in
  • limit - sdword in

Return Value

None

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_timeout_occured - JALlib Procedures Help

ina3221_timeout_occured JALLIB FUNCTION

Signature

function ina3221_timeout_occured() return bit is

Description

Returns TRUE if a timeout occured in one of the read functions or in case of
timeout on the IIC bus if the IIC timeout is defined. Value is cleared after
a call to this function.

Include

To use this procedure, include the library:

include ina3221

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


ina3221_warning_alert - JALlib Procedures Help

ina3221_warning_alert JALLIB FUNCTION

Signature

function ina3221_warning_alert(word in flags, byte in channel) return bit is

Description

Returns TRUE if the warning alert for the given channel is active.
Channel in range 0..2. Channel must be active for the alert.

Include

To use this procedure, include the library:

include ina3221

Parameters

  • flags - word in
  • channel - byte in

Return Value

bit - Function return value

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: ina3221.jal


int_on_change_callback_0 - JALlib Procedures Help

int_on_change_callback_0 JALLIB PROCEDURE

Signature

procedure int_on_change_callback_0() is

Description

interrupt for interrupt on change pin3
interrupt for interrupt on change pin 0

Include

To use this procedure, include the library:

include servo_rc_slave

Parameters

None

Return Value

None

Example

From sample file: 18f4620_interrupt_on_change.jal

-- Title: Interrupt on change sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample uses interrupt on change pins to set the state of
--              a led. The interrupt on change pin takes input from another
--              pin that is used to create a clock pulse.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B.
-- Check your datasheet for a interrupt-on-change pin.
-- Input must be clear to reduce unwanted interrupts.
--
-- Connect clock_out pin directly to int_on_change pin.
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--

-- set all IO as digital
enable_digital_io()

alias led0                       is pin_a0
alias led0_direction             is pin_a0_direction
led0_direction = output

alias led1                       is pin_a1
alias led1_direction             is pin_a1_direction
led1_direction = output

alias clock_out           is pin_a2
alias clock_out_direction is pin_a2_direction
clock_out_direction = output

-- choose pins to use for int on change
const byte int_on_change_pins[] = {"B",4, "B",5}
include interrupt_on_change
int_on_change_init()

-- interrupt for pin B4
procedure int_on_change_callback_0() is
   pragma inline
   led0 = int_on_change_0
end procedure

-- interrupt for pin B5
procedure int_on_change_callback_1() is
   pragma inline
   led1 = int_on_change_1
end procedure

-- main loop
forever loop
   clock_out = high
   _usec_delay(250_000)
   clock_out = low
   _usec_delay(250_000)
end loop

Generated by JALlib CHM Help System | Source: servo_rc_slave.jal


int_on_change_callback_1 - JALlib Procedures Help

int_on_change_callback_1 JALLIB PROCEDURE

Signature

procedure int_on_change_callback_1() is

Description

interrupt for interrupt on change pin 1

Include

To use this procedure, include the library:

include servo_rc_slave

Parameters

None

Return Value

None

Example

From sample file: 18f4620_interrupt_on_change.jal

-- Title: Interrupt on change sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample uses interrupt on change pins to set the state of
--              a led. The interrupt on change pin takes input from another
--              pin that is used to create a clock pulse.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B.
-- Check your datasheet for a interrupt-on-change pin.
-- Input must be clear to reduce unwanted interrupts.
--
-- Connect clock_out pin directly to int_on_change pin.
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--

-- set all IO as digital
enable_digital_io()

alias led0                       is pin_a0
alias led0_direction             is pin_a0_direction
led0_direction = output

alias led1                       is pin_a1
alias led1_direction             is pin_a1_direction
led1_direction = output

alias clock_out           is pin_a2
alias clock_out_direction is pin_a2_direction
clock_out_direction = output

-- choose pins to use for int on change
const byte int_on_change_pins[] = {"B",4, "B",5}
include interrupt_on_change
int_on_change_init()

-- interrupt for pin B4
procedure int_on_change_callback_0() is
   pragma inline
   led0 = int_on_change_0
end procedure

-- interrupt for pin B5
procedure int_on_change_callback_1() is
   pragma inline
   led1 = int_on_change_1
end procedure

-- main loop
forever loop
   clock_out = high
   _usec_delay(250_000)
   clock_out = low
   _usec_delay(250_000)
end loop

Generated by JALlib CHM Help System | Source: servo_rc_slave.jal


int_on_change_init - JALlib Procedures Help

int_on_change_init JALLIB PROCEDURE

Signature

procedure int_on_change_init() is

Description

init interrupt on change pins

Include

To use this procedure, include the library:

include interrupt_on_change

Parameters

None

Return Value

None

Example

From sample file: 18f4525_servo_rc_slave.jal

-- Title: RC Servo Slave sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows your PIC to read pulses given by a RC
--              receiver. Connect your PIC to a rc receiver the same way you
--              would connect a RC servo. This will use the rc_servo_slave
--              library to output a value to the serial port dependant on
--              where your fingers are moving the controls on your remote
--              transmitter. PIC will read the pulse width at the receiver.
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B. If you are using another
-- port, INTCON_RBIE & INTCON_RBIF may be named differently.
-- Check your datasheet for a interrupt-on-change pin.
--
-- Connect clock_out pin directly to int_on_change pin for an example without
-- an actual RC receiver.
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- choose pins to use for interrupt on change
const byte int_on_change_pins[] = {"B",4,"B",5} -- interrupt on change pin 0 and 1,  B4 and B5
include interrupt_on_change
int_on_change_init()

-- setup servo slave lib
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_0 = TRUE -- use interrupt on change pin 0
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_1 = TRUE -- use interrupt on change pin 1
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_2 = 0 -- use interrupt on change pin 2
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_3 = 0 -- use interrupt on change pin 3
--
const SERVO_SLAVE_USE_TIMER = 1     -- choose a timer
--
-- set your min/max values (0 to 100)
-- adjust SERVO_SLAVE_MIN first, then adjust SERVO_SLAVE_MAX
-- so output values will range from 0 to 255.
const SERVO_SLAVE_MIN = 0 -- default is 0
const SERVO_SLAVE_MAX = 0 -- default is 0
--
include servo_rc_slave
servo_slave_init()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on() -- turn on PWM1
pwm2_on() -- turn on PWM1

-- define clock out pin
alias clock_out           is pin_a1
alias clock_out_direction is pin_a1_direction
clock_out_direction = output

-- main loop
forever loop
   -- create a pulse to measure
   -- if your receiver is not connected, you may use this signal.
   clock_out = high
   _usec_delay(1500) -- 500 to 2_500 (0.5ms to 2.5ms)
   clock_out = low
   _usec_delay(20_000)

   -- SIGNAL 1
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[0] == TRUE then
      -- set the led brightness
      pwm1_set_dutycycle_ratio( servo_slave[0] << 2)
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[0])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm1_set_dutycycle_ratio(0) -- turn led off
   end if

   serial_data = " "
   serial_data = "-"
   serial_data = " "

   -- SIGNAL 2
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[1] == TRUE then
      -- set the led brightness
      pwm2_set_dutycycle_ratio( servo_slave[1] << 2 )
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[1])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm2_set_dutycycle_ratio(1) -- turn led off
   end if

   -- send crlf to serial port
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: interrupt_on_change.jal


int_on_change_isr - JALlib Procedures Help

int_on_change_isr JALLIB PROCEDURE

Signature

procedure int_on_change_isr() is

Description

init interrupt on change pins

Include

To use this procedure, include the library:

include interrupt_on_change

Parameters

None

Return Value

None

Example

From sample file: 16f88_blinkstop_on_interrupt_demo.jal

-- ------------------------------------------------------
-- Title: Blink-a-led with stop on INT demo
--
-- Author: Sunish Issac, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This program blinks an led on pin a0 and stops the blink on a high pulse on interrupt
-- pin 6 with is RB0/INT on 16f88
--
-- This file has been generated by hand (manually maintained)
--
include 16f88                    -- target PICmicro
--
pragma target clock 8_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC    INTOSC_NOCLKOUT -- internal osc
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      enabled      -- allow Low Voltage Programming
pragma target MCLR     internal     -- reset internal

OSCCON_IRCF = 0b111                -- use 8 MHz internal oscillator

enable_digital_io()                -- make all pins digital I/O
--
alias   led      is pin_A0
pin_A0_direction =  output
--
var volatile bit stopblink = false

procedure int_on_change_isr() is
   pragma interrupt
if  INTCON_INTF then
 stopblink = true     ; can be true only in isr
 INTCON_INTF = false
end if

end procedure

INTCON_GIE  = TRUE        -- Enables all unmasked interrupts
INTCON_INTE = TRUE        -- enable INT0 PIN for interrupts
OPTION_REG_INTEDG = 1     -- rising edge

forever loop
  if ! stopblink then ;make led on only while stopblink bit is false
     led = on
  end if
   _usec_delay(250_000)
   led = off
   _usec_delay(250_000)

end loop
--

Generated by JALlib CHM Help System | Source: interrupt_on_change.jal


interrupt_on_change.jal - JALLIB Library Documentation

interrupt_on_change.jal JALLIB LIBRARY

Title

Interrupt on change library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library allows use of interrupt on change pins.

Sources

notes:
This library seems large, but it takes advantage of the compilers ability
to reduce code via constants in if statements.

------------------------------------------------------------------------------
16F Midrange code
------------------------------------------------------------------------------
constants

Constants and Variables

INT_ON_CHANGE_PIN_COUNT - const byte = count(INT_ON_CHANGE_PINS) / 2
INT_ON_CHANGE_PIN_COUNT - const byte = count(INT_ON_CHANGE_PINS) / 2
pin_states - var byte
int_on_change_pin_state_0 - var byte
int_on_change_pin_state_1 - var byte
int_on_change_pin_state_2 - var byte
int_on_change_pin_state_3 - var byte
int_on_change_pin_state_4 - var byte
int_on_change_pin_state_5 - var byte
int_on_change_pin_state_6 - var byte
int_on_change_pin_state_7 - var byte

Routines

  • int_on_change_init - Procedure
  • int_on_change_init - Procedure
  • int_on_change_isr - Procedure
  • int_on_change_isr - Procedure
  • int_on_change_proc_0 - Procedure
  • int_on_change_proc_0 - Procedure
  • int_on_change_proc_0 - Procedure
  • int_on_change_proc_0 - Procedure
  • int_on_change_proc_1 - Procedure
  • int_on_change_proc_1 - Procedure
  • int_on_change_proc_1 - Procedure
  • int_on_change_proc_1 - Procedure
  • int_on_change_proc_2 - Procedure
  • int_on_change_proc_2 - Procedure
  • int_on_change_proc_2 - Procedure
  • int_on_change_proc_2 - Procedure
  • int_on_change_proc_3 - Procedure
  • int_on_change_proc_3 - Procedure
  • int_on_change_proc_3 - Procedure
  • int_on_change_proc_3 - Procedure
  • int_on_change_proc_4 - Procedure
  • int_on_change_proc_4 - Procedure
  • int_on_change_proc_4 - Procedure
  • int_on_change_proc_4 - Procedure
  • int_on_change_proc_5 - Procedure
  • int_on_change_proc_5 - Procedure
  • int_on_change_proc_5 - Procedure
  • int_on_change_proc_5 - Procedure
  • int_on_change_proc_6 - Procedure
  • int_on_change_proc_6 - Procedure
  • int_on_change_proc_6 - Procedure
  • int_on_change_proc_6 - Procedure
  • int_on_change_proc_7 - Procedure
  • int_on_change_proc_7 - Procedure
  • int_on_change_proc_7 - Procedure
  • int_on_change_proc_7 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_0 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_1 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_2 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_3 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_4 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_5 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_6 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure
  • int_on_edge_proc_7 - Procedure


ip_header.jal - JALLIB Library Documentation

ip_header.jal JALLIB LIBRARY

Title

Creates a IP Header BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library creates a IP header

Sources

http://www.faqs.org/rfcs/rfc791.html
http://www.tekelec.com/ss7/protocols/ip2.asp
http://www.networksorcery.com/enp/protocol/ip.htm

protocol types, for "IP_HEADER_PROTOCOL"

Constants and Variables

ICMP - const byte = 1 -- ICMP protocol number for ip header
ICMP protocol number for ip header
UDP - const byte = 17 -- UDP protocol number for ip header
UDP protocol number for ip header
TCP - const byte = 6 -- TCP protocol number for ip header
TCP protocol number for ip header
ip_header_size - var byte = 20

Routines

  • ip_header_create - Procedure
  • ip_header_read_packet - Procedure
  • ip_header_set_source_ip - Procedure
  • ip_header_verify - Function returns byte


ir_ranger_gp2d02.jal - JALLIB Library Documentation

ir_ranger_gp2d02.jal JALLIB LIBRARY

Title

GP2D02 IR ranger library

Author

Sebastien Lelong, Copyright (c) 2008-2009, all rights reserved., Adapted-by:

Compiler

>=2.4k

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this lib is able to handle the GP2D02 lib, reading distance
measure with this IR Ranger.
--
You can either use the read procedure, or access the pseudo-variable
to retrieve distance measures.
--
When defining pins the ranger is connected to to, it's important to
set them as "volatile" (level will go low/high within function call)
See sample(s) for more.

Notes

reading a distance can take quite a long time, approx. 74ms.
See datasheet for more, but you should remember this while using this IR ranger

Sources

- datasheet: http://www.datasheetcatalog.org/datasheet/Sharp/mXvryzu.pdf

Routines

  • gp2d02_read_pins - Function returns byte


jascii.jal - JALLIB Library Documentation

jascii.jal JALLIB LIBRARY

Title

ASCII text character constants and case conversion procedures

Author

Wouter van Ooijen, Copyright (c) 1998, all rights reserved., Adapted-by: Joep Suijs, Rob Hamerling

Compiler

>=2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

- ASCII text character constant definitions
- case conversion procedures toupper and tolower
--
use of toupper
var byte char = "b" -- assign lower case "b" to char
toupper(char) -- char now contains "B"

Constants and Variables

ASCII_NULL - const byte = 00
ASCII_SOH - const byte = 01
ASCII_STX - const byte = 02
ASCII_ETX - const byte = 03
ASCII_EOT - const byte = 04
ASCII_ENQ - const byte = 05
ASCII_ACK - const byte = 06
ASCII_BEL - const byte = 07
ASCII_BS - const byte = 08
ASCII_HT - const byte = 09
ASCII_LF - const byte = 10
ASCII_VT - const byte = 11
ASCII_FF - const byte = 12
ASCII_CR - const byte = 13
ASCII_SO - const byte = 14
ASCII_SI - const byte = 15
ASCII_DLE - const byte = 16
ASCII_DC1 - const byte = 17
ASCII_DC2 - const byte = 18
ASCII_DC3 - const byte = 19
ASCII_DC4 - const byte = 20
ASCII_NAK - const byte = 21
ASCII_SYN - const byte = 22
ASCII_ETB - const byte = 23
ASCII_CAN - const byte = 24
ASCII_EM - const byte = 25
ASCII_SUB - const byte = 26
ASCII_ESC - const byte = 27
ASCII_FS - const byte = 28
ASCII_GS - const byte = 29
ASCII_RS - const byte = 30
ASCII_US - const byte = 31
ASCII_SP - const byte = 32
ASCII_DEL - const byte = 127

Routines

  • tolower - Procedure
  • toupper - Procedure


keyboard.jal - JALLIB Library Documentation

keyboard.jal JALLIB LIBRARY

Title

keyboard, scans 4x4 keybaord and returns 0x00..0x0F is keypressed, 0x10 if none pressed

Author

Javier Martnez, Copyright (c) 2003, all rights reserved., Adapted-by: Eur van Andel, eur@fiwihex.nl, Joep Suijs, Rob Hamerling

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is used to scan a 4x3 or 4x4 keyboard.
To use it, you need to define three variables:
keydrive is the half port (_high or _low) with the cols connected.
keydrive_direction is the related direction register.
keyscan is the half port (_high or _low) with the rows connected.
--
Example:
--
var volatile byte keyscan is porta_low -- rows of keyboard
var volatile byte keydrive is portb_low -- columns of keyboard
var volatile byte keydrive_direction is portb_low_direction
include keyboard
Note: if you don't want keyboard.jal change the direction of your pins, make sure all
keydrive pins are set to output before you call the library and define:
var volatile byte keydrive_direction is keydrive
--
The library has two functions to read the keyboard:
getkey() returns the key pressed.
getkey_once() returns a pressed key only once (and 'none', 0x10 until the next key is pressed)
--
Hardware setup: connect the keyboard rows to a half port (higher or lower 4 bits of a port)
and connect the cols to a half port. Put a pull-down resistor (10k - 47k) on each row pin.
Adaptation: soldering your wires in the right order is a lot harder than you think.
Make sure you keep the rows and cols together and connect them to right port.
You could either adapt your wiring to match the default configuration or reconfigure the
library by defining the next 8 constants before you include keyboard.jal, like:
const row1 = 0b0000_0100
const row2 = 0b0000_0001
const row3 = 0b0000_0010
const row4 = 0b0000_1000
const col1 = 0b0000_1000
const col2 = 0b0000_0010
const col3 = 0b0000_0100
const col4 = 0b0000_0001
Connect the keyboard and press the buttons. Adapt the row and column constants so
pressing the buttons give the right result.
Note: you need to specify all 8 constants, even when you have a 4x3 keyboard. In
this case you can specify:
const col4 = 0b0000_0000
--
keyboard map (4x4, col4 is left out with 4x3 keyboard)
--
1 2 3 C row 1
4 5 6 D row 2
7 8 9 E row 3
* 0 # F row 4
--
col 1 2 3 4

Notes

[RobH] Added a 1 microsecond delay after changing keydrive
to obtain reliable results with oscillator frequencies
of 8 MHz and higher
----------------------------------------------------------------------------

Constants and Variables

lastkey - var byte = 0xff

Routines

  • getkey - Function returns byte
  • getkey_once - Function returns byte


large_array_1.jal - JALLIB Library Documentation

large_array_1.jal JALLIB LIBRARY

Title

Large Array_1 library

Author

Oliver "Kiste" Seitz, copyright (c) 2009..2020, all rights reserved., Adapted-by:

Compiler

>=2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is for creating an array that take up more than one
GPR segment of memory. Works for PIC14(H) and PIC16 cores. It is
a complete rewrite of the original large_array_1 lib.

Notes

For controllers with PIC16 core (labeled PIC18(l)f...)
Supports byte array with up to 14848 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 7424 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 3712 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
For controllers with PIC14 core (labeled PIC16(l)f... or PIC12(l)f...)
Supports byte array with up to 4800 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 2400 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 1200 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
Creates an array named large_array_1
Use "alias new_array_name is large_array_1" to rename the array
Example:
const LARGE_ARRAY_1_SIZE = 600 -- choose number of array variables, not bytes
const LARGE_ARRAY_1_VARIABLE_SIZE = 2 -- choose size of variables (word)
include large_array_1 -- include the array library
alias my_array is large_array_1 -- rename/alias the array to suit your program
Important: There is no range check on the index in the array.

Check for the target CPU

Sources

This file is generated by script: generate_large_array.py

Constants and Variables

section - var byte
section - var byte
section - var byte

Routines

  • large_array_1'put - Procedure
  • large_array_1'put - Procedure
  • large_array_1'put - Procedure
  • large_array_1'put - Procedure
  • large_array_1'put - Procedure
  • large_array_1'put - Procedure


large_array_2.jal - JALLIB Library Documentation

large_array_2.jal JALLIB LIBRARY

Title

Large Array_2 library

Author

Oliver "Kiste" Seitz, copyright (c) 2009..2020, all rights reserved., Adapted-by:

Compiler

>=2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is for creating an array that take up more than one
GPR segment of memory. Works for PIC14(H) and PIC16 cores. It is
a complete rewrite of the original large_array_2 lib.

Notes

For controllers with PIC16 core (labeled PIC18(l)f...)
Supports byte array with up to 14848 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 7424 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 3712 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
For controllers with PIC14 core (labeled PIC16(l)f... or PIC12(l)f...)
Supports byte array with up to 4800 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 2400 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 1200 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
Creates an array named large_array_2
Use "alias new_array_name is large_array_2" to rename the array
Example:
const LARGE_ARRAY_2_SIZE = 600 -- choose number of array variables, not bytes
const LARGE_ARRAY_2_VARIABLE_SIZE = 2 -- choose size of variables (word)
include large_array_2 -- include the array library
alias my_array is large_array_2 -- rename/alias the array to suit your program
Important: There is no range check on the index in the array.

Check for the target CPU

Sources

This file is generated by script: generate_large_array.py

Constants and Variables

section - var byte
section - var byte
section - var byte

Routines

  • large_array_2'put - Procedure
  • large_array_2'put - Procedure
  • large_array_2'put - Procedure
  • large_array_2'put - Procedure
  • large_array_2'put - Procedure
  • large_array_2'put - Procedure


large_array_3.jal - JALLIB Library Documentation

large_array_3.jal JALLIB LIBRARY

Title

Large Array_3 library

Author

Oliver "Kiste" Seitz, copyright (c) 2009..2020, all rights reserved., Adapted-by:

Compiler

>=2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is for creating an array that take up more than one
GPR segment of memory. Works for PIC14(H) and PIC16 cores. It is
a complete rewrite of the original large_array_3 lib.

Notes

For controllers with PIC16 core (labeled PIC18(l)f...)
Supports byte array with up to 14848 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 7424 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 3712 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
For controllers with PIC14 core (labeled PIC16(l)f... or PIC12(l)f...)
Supports byte array with up to 4800 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 2400 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 1200 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
Creates an array named large_array_3
Use "alias new_array_name is large_array_3" to rename the array
Example:
const LARGE_ARRAY_3_SIZE = 600 -- choose number of array variables, not bytes
const LARGE_ARRAY_3_VARIABLE_SIZE = 2 -- choose size of variables (word)
include large_array_3 -- include the array library
alias my_array is large_array_3 -- rename/alias the array to suit your program
Important: There is no range check on the index in the array.

Check for the target CPU

Sources

This file is generated by script: generate_large_array.py

Constants and Variables

section - var byte
section - var byte
section - var byte

Routines

  • large_array_3'put - Procedure
  • large_array_3'put - Procedure
  • large_array_3'put - Procedure
  • large_array_3'put - Procedure
  • large_array_3'put - Procedure
  • large_array_3'put - Procedure


large_array_4.jal - JALLIB Library Documentation

large_array_4.jal JALLIB LIBRARY

Title

Large Array_4 library

Author

Oliver "Kiste" Seitz, copyright (c) 2009..2020, all rights reserved., Adapted-by:

Compiler

>=2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is for creating an array that take up more than one
GPR segment of memory. Works for PIC14(H) and PIC16 cores. It is
a complete rewrite of the original large_array_4 lib.

Notes

For controllers with PIC16 core (labeled PIC18(l)f...)
Supports byte array with up to 14848 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 7424 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 3712 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
For controllers with PIC14 core (labeled PIC16(l)f... or PIC12(l)f...)
Supports byte array with up to 4800 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 2400 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 1200 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
Creates an array named large_array_4
Use "alias new_array_name is large_array_4" to rename the array
Example:
const LARGE_ARRAY_4_SIZE = 600 -- choose number of array variables, not bytes
const LARGE_ARRAY_4_VARIABLE_SIZE = 2 -- choose size of variables (word)
include large_array_4 -- include the array library
alias my_array is large_array_4 -- rename/alias the array to suit your program
Important: There is no range check on the index in the array.

Check for the target CPU

Sources

This file is generated by script: generate_large_array.py

Constants and Variables

section - var byte
section - var byte
section - var byte

Routines

  • large_array_4'put - Procedure
  • large_array_4'put - Procedure
  • large_array_4'put - Procedure
  • large_array_4'put - Procedure
  • large_array_4'put - Procedure
  • large_array_4'put - Procedure


large_array_5.jal - JALLIB Library Documentation

large_array_5.jal JALLIB LIBRARY

Title

Large Array_5 library

Author

Oliver "Kiste" Seitz, copyright (c) 2009..2020, all rights reserved., Adapted-by:

Compiler

>=2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is for creating an array that take up more than one
GPR segment of memory. Works for PIC14(H) and PIC16 cores. It is
a complete rewrite of the original large_array_5 lib.

Notes

For controllers with PIC16 core (labeled PIC18(l)f...)
Supports byte array with up to 14848 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 7424 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 3712 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
For controllers with PIC14 core (labeled PIC16(l)f... or PIC12(l)f...)
Supports byte array with up to 4800 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 2400 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 1200 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
Creates an array named large_array_5
Use "alias new_array_name is large_array_5" to rename the array
Example:
const LARGE_ARRAY_5_SIZE = 600 -- choose number of array variables, not bytes
const LARGE_ARRAY_5_VARIABLE_SIZE = 2 -- choose size of variables (word)
include large_array_5 -- include the array library
alias my_array is large_array_5 -- rename/alias the array to suit your program
Important: There is no range check on the index in the array.

Check for the target CPU

Sources

This file is generated by script: generate_large_array.py

Constants and Variables

section - var byte
section - var byte
section - var byte

Routines

  • large_array_5'put - Procedure
  • large_array_5'put - Procedure
  • large_array_5'put - Procedure
  • large_array_5'put - Procedure
  • large_array_5'put - Procedure
  • large_array_5'put - Procedure


large_array_6.jal - JALLIB Library Documentation

large_array_6.jal JALLIB LIBRARY

Title

Large Array_6 library

Author

Oliver "Kiste" Seitz, copyright (c) 2009..2020, all rights reserved., Adapted-by:

Compiler

>=2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library is for creating an array that take up more than one
GPR segment of memory. Works for PIC14(H) and PIC16 cores. It is
a complete rewrite of the original large_array_6 lib.

Notes

For controllers with PIC16 core (labeled PIC18(l)f...)
Supports byte array with up to 14848 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 7424 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 3712 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
For controllers with PIC14 core (labeled PIC16(l)f... or PIC12(l)f...)
Supports byte array with up to 4800 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 1)
Supports word array with up to 2400 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 2)
Supports dword array with up to 1200 entries (LARGE_ARRAY_1_VARIABLE_SIZE = 4)
Creates an array named large_array_6
Use "alias new_array_name is large_array_6" to rename the array
Example:
const LARGE_ARRAY_6_SIZE = 600 -- choose number of array variables, not bytes
const LARGE_ARRAY_6_VARIABLE_SIZE = 2 -- choose size of variables (word)
include large_array_6 -- include the array library
alias my_array is large_array_6 -- rename/alias the array to suit your program
Important: There is no range check on the index in the array.

Check for the target CPU

Sources

This file is generated by script: generate_large_array.py

Constants and Variables

section - var byte
section - var byte
section - var byte

Routines

  • large_array_6'put - Procedure
  • large_array_6'put - Procedure
  • large_array_6'put - Procedure
  • large_array_6'put - Procedure
  • large_array_6'put - Procedure
  • large_array_6'put - Procedure


lcd_backlight - JALlib Procedures Help

lcd_backlight JALLIB PROCEDURE

Signature

procedure lcd_backlight(bit in onoff) is

Description

lcd_backlight - turn backlite on/off

Include

To use this procedure, include the library:

include lcd_backlight

Parameters

  • onoff - bit in

Return Value

None

Example

From sample file: 18f67j50_sr_74595.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for 74595 shift register
--
-- Author: Joep Suijs, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    test setup: 3 x 74595 cascaded
--    sr_sda connects to SER_IN / DS pin of 74595 #1
--    SER_OUT / Q7S of 74595 #1 connects to SER_IN / DS pin of 74595 #2
--    SER_OUT / Q7S of 74595 #2 connects to SER_IN / DS pin of 74595 #3
--    sr_scl is connected the SRCK / SHCP pin of all three 74595 chips
--    sr_rck is connected the RCK / STCP pin of all three 74595 chips
--    sr_g is connected the G / OE pin of all three 74595 chips
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_sr_74595.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

enable_digital_io() -- disable analog I/O (if any)

include delay
include seven_segment

-- define IO pin's
alias sr_rck   is pin_a0   ; RCK (parallel clock / load, rising edge)
alias sr_sda   is pin_a1   ; SER_IN   / DS
alias sr_scl   is pin_a2   ; SRCK  (serial clock, rising egde)
alias sr_g     is pin_a3   ; G (output enable, low = enable)

-- set IO pins to output
pin_a0_direction = output
pin_a1_direction = output
pin_a2_direction = output
pin_a3_direction = output

-- include library & turn outputs on
include shift_register_74595
sr_output_enable(1)  ; activate shift register outputs

forever loop

   -- set one output of each shift register
   sr_write(1)   ; data for 74595 #3 (end of chain)
   sr_write(2)   ; data for 74595 #2 (middle one)
   sr_write(4)   ; data for 74595 #1 (directly connected to PIC)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- show numbers on seven segment display, connected to shift register
   sr_write(seven_from_digit(1))
   sr_write(seven_from_digit(2))
   sr_write(seven_from_digit(3))
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- clear outputs of all 3 shift registers
   sr_write(0)
   sr_write(0)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- set all outputs of shift register #1
   sr_write(255)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #2 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #3 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs are low now)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

end loop

Generated by JALlib CHM Help System | Source: lcd_backlight.jal


lcd_backlight.jal - JALLIB Library Documentation

lcd_backlight.jal JALLIB LIBRARY

Title

lcd_backlight.jal

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Provides standard interface to backlight of (directly connected) lcd.
First, setup the pin for the backlight:
var volatile bit lcd_bl is pin_b0
pin_b0_direction = output
--
If the backlight line is inverted (that is low output turn the backlight on),
you must define:
const bit lcd_bl_inverted = true
--
If you want digital backlight (on or off), then you can include this library.
But if you want variable backlight (256 steps from off to on), the pin above
must be a pwm (ccp) output pin. And you have to tell the library, which pwm:
const byte lcd_backlight_pwm = 1
--
now include the library & init it:
include lcd_backlight
pwm_backlight_init()

Notes

----------------------------------------------------------------------------

define default

Constants and Variables

lcd_bl_inverted - const bit = false

Routines

  • lcd_backlight - Procedure
  • lcd_backlight_variable - Procedure
  • lcd_backlight_variable - Procedure
  • lcd_backlight_variable - Procedure
  • lcd_backlight_variable - Procedure
  • lcd_backlight_variable - Procedure
  • pwm_backlight_init - Procedure
  • pwm_backlight_init - Procedure
  • pwm_backlight_init - Procedure
  • pwm_backlight_init - Procedure
  • pwm_backlight_init - Procedure
  • pwm_backlight_init - Procedure


lcd_backlight_variable - JALlib Procedures Help

lcd_backlight_variable JALLIB PROCEDURE

Signature

procedure lcd_backlight_variable(byte in value) is

Description

No description available.

Include

To use this procedure, include the library:

include lcd_backlight

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f877_backlight.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for lcd_backlight test (basic test)
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
-- setup:   A hd44780 compatible display, used in 4-bit mode with backlight
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_backlight.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b5              -- LCD command/data select.
alias lcd_rs_direction is pin_b5_direction
alias lcd_en           is pin_b4              -- LCD data trigger
alias lcd_en_direction is pin_b4_direction

-- primary dataport nibble:
alias lcd_dataport is portb_low              -- LCD data  port
alias lcd_dataport_direction is portb_low_direction

-- alternative dataport bits:
alias lcd_d4 is pin_b0
alias lcd_d5 is pin_b1
alias lcd_d6 is pin_b2
alias lcd_d7 is pin_b3
alias lcd_d4_direction is pin_b0_direction
alias lcd_d5_direction is pin_b1_direction
alias lcd_d6_direction is pin_b2_direction
alias lcd_d7_direction is pin_b3_direction

const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line

;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction
;@jallib section ccp
-- backlight control (can be variable and digital on this pin)
alias lcd_bl is pin_c2
alias lcd_bl_direction is pin_c2_direction

enable_digital_io() -- disable analog I/O (if any)

-- setup libs, io etc
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include print
include lcd_hd44780_4
include delay
lcd_init()                              -- initialize LCD

lcd_clear_screen()
lcd_home()

const byte teststring[] = "Backlight test."
print_string(lcd, teststring)

const byte lcd_backlight_pwm = 1 -- by selecting the pwm pin, lcd_backlight_variable() is enabled.
lcd_bl_direction = output
;const bit lcd_bl_inverted = true   -- define this when pin low turns backlight on

-- include & init backlight lib
include lcd_backlight
pwm_backlight_init()

var byte i
forever loop

   -- set backlight off for two seconds
   lcd_backlight(off)
   delay_100ms(20)

   -- set backlight on for two seconds
   lcd_backlight(on)
   delay_100ms(20)

   if(defined(lcd_backlight_pwm) == true) then

      -- we have variable backlight!

      -- first increase intensity
      for 255 using i loop
         lcd_backlight_variable(i)
         delay_1ms(10)
      end loop

      -- and decrease intensity
      for 255 using i loop
         lcd_backlight_variable(255-i)
         delay_1ms(10)
      end loop

   end if

end loop

Generated by JALlib CHM Help System | Source: lcd_backlight.jal


lcd_clear_line - JALlib Procedures Help

lcd_clear_line JALLIB PROCEDURE

Signature

procedure lcd_clear_line(byte in line) is

Description

lcd_clear_line - clears the line "line" of the LCD

Include

To use this procedure, include the library:

include lcd_hd44780_common

Parameters

  • line - byte in

Return Value

None

Example

From sample file: 16f877a_ds1307_sw.jal

-- ------------------------------------------------------
-- Title:  DS1307 - Real Time Clock
--
-- Author: Enzo SERAFINI, Copyright (c) 2011, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This sample show an example to setup hours, minutes and seconds and display on LCD
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:  Jean-Bernard - DS1307 lib.
--
-- Notes:
--  - File creation date/time: 13 Jun 2011.
--
-- ------------------------------------------------------

include 16f877a                    -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC      HS               -- HS crystal or resonator
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      enabled      -- allow Low Voltage Programming
-- These configuration bit settings are only a selection, sufficient for
-- this program, but other programs may need more or different settings.
--
enable_digital_io()                -- make all pins digital I/O

-- lcd config
const byte LCD_ROWS    =  4           -- LCD with 4 lines
const byte LCD_CHARS   =  20          -- and 20 characters per line
--
alias     lcd_en       is pin_D4      -- data trigger
alias     lcd_rs       is pin_D5      -- command/data select.
pin_D4_direction       = output
pin_D5_direction       = output
--
alias     lcd_d4       is pin_D0
alias     lcd_d5       is pin_D1
alias     lcd_d6       is pin_D2
alias     lcd_d7       is pin_D3
--
pin_D0_direction       = output
pin_D1_direction       = output
pin_D2_direction       = output
pin_D3_direction       = output
--
include lcd_hd44780_4
--
lcd_init()                            -- init the lcd controller

-- i2c config
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)

include i2c_software    -- include i2c software lib

i2c_initialize()

include delay           -- include delay lib
include print           -- include print lib
include format          -- include format lib

include rtc_ds1307          -- include ds1307 rtc lib

ds1307_init()

-- define strings

var byte str1[] = "Set Time"
var byte str2[] = "hours"
var byte str3[] = "minutes"
var byte str4[] = "seconds"
var byte str5[] = "RTC :"

-- define variables

var byte h , m , s

-- define pins

alias     sw1       is pin_A0
alias     sw2       is pin_A1
alias     sw3       is pin_A2
--
pin_A0_direction       = input
pin_A1_direction       = input
pin_A2_direction       = input

-- Setup hours, minutes and seconds

lcd_cursor_position( 0,0 )
print_string(lcd,str1)                        -- Display "Set Time"
delay_100ms(10)
h = 0
while sw1 != high loop                        -- Setup hours

   if sw2 == high then h = h + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then h = h - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if h == 24 then h = 0 end if
   if h == 255 then h = 23 end if
   lcd_cursor_position( 1,0 )
   print_string(lcd,str2)                    -- Display "hours"
   lcd_cursor_position( 1,9 )
   format_byte_dec(lcd,h,2,0)               -- Display set hours
end loop
delay_100ms(10)
m = 0
while sw1 != high loop                        -- Setup minutes
   if sw2 == high then m = m + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then m = m - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if m == 60 then m = 0 end if
   if m == 255 then m = 59 end if
   lcd_cursor_position( 2,0 )
   print_string(lcd,str3)                    -- Display "minutes"
   lcd_cursor_position( 2,9 )
   format_byte_dec(lcd,m,2,0)               -- Display set minutes
end loop
delay_100ms(10)
s = 0
while sw1 != high loop                        -- Setup seconds
   if sw2 == high then s = s + 1  end if
   while sw2 == high loop
      delay_1ms(10)
   end loop
   if sw3 == high then s = s - 1  end if
   while sw3 == high loop
      delay_1ms(10)
   end loop

   if s == 60 then s = 0 end if
   if s == 255 then s = 59 end if
   lcd_cursor_position( 3,0 )
   print_string(lcd,str4)                    -- Display "seconds"
   lcd_cursor_position( 3,9)
   format_byte_dec(lcd,s,2,0)               -- Dsiplay set seconds
end loop

-- write hours, minutes and seconds in the DS1307

ds1307_write( 0x00 , s )      -- seconds
ds1307_write( 0x01 , m )      -- minutes
ds1307_write( 0x02 , h )      -- hours

lcd_clear_line(0)

forever loop

   ds1307_read( 0x00 , s )      -- seconds
   ds1307_read( 0x01 , m )      -- minutes
   ds1307_read( 0x02 , h )      -- hours

   lcd_cursor_position( 0,0 )
   print_string(lcd,str5)        -- Display "RTC :"
   lcd_cursor_position( 0,7 )
   format_time_hms(lcd,h, m,s)   -- Display hh:mm:ss

end loop

Generated by JALlib CHM Help System | Source: lcd_hd44780_common.jal


lcd_clear_screen - JALlib Procedures Help

lcd_clear_screen JALLIB PROCEDURE

Signature

procedure lcd_clear_screen() is

Description

lcd_clear_screen - clears the LCD

Include

To use this procedure, include the library:

include lcd_hd44780_common

Parameters

None

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: lcd_hd44780_common.jal


lcd_cursor_position - JALlib Procedures Help

lcd_cursor_position JALLIB PROCEDURE

Signature

procedure lcd_cursor_position(byte in line, byte in pos) is

Description

lcd_cursor_position - Specify row and column (0-based)
.
About cursor positions: the LCDs are internally 2x40 char devices.
The first line starts at offset 0, the second line at offset 64 (0x40).
With 4 line devices the third and fourth line are addressed as extensions
of the first and second line by adding an offset. For a 4x20 line device
the offset is 20, for a 4x16 line display the offset is 16 or 20.
Declare the constant LCD_CHARS as appropriate for your screen
(you may have to specify 20 even if your display has only 16 chars!).
.
Note: Some 1x16 LCDs are implemented as 2x8 line LCDs, which means that
the second half of the line has to be handled as the second line.

Include

To use this procedure, include the library:

include lcd_hd44780_common

Parameters

  • line - byte in
  • pos - byte in

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: lcd_hd44780_common.jal


lcd_define - JALlib Procedures Help

lcd_define JALLIB PROCEDURE

Signature

procedure lcd_define(byte in pos, byte in str[]) is

Description

lcd_define - Create a custom character
The characters can be placed on position 0-7 of the character ram
.
pos: position of the character
str[]: array containing the custom character
.
(0xFF is a common pattern)

Include

To use this procedure, include the library:

include lcd_hd44780_common

Parameters

  • pos - byte in
  • str[] - byte in

Return Value

None

Example

From sample file: 18f2450_lcd_hd44780_custom.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for custom chars on lcd_hd44780.
-- Author: Joep Suijs, Copyright (c) 2011-2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- This sample shows how to setup an LCD for use with custom characters.
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources: Diego Demeulemeester (http://tech.groups.yahoo.com/group/jallist/message/29985)
--
-- Notes:
-- setup: an hd44780 compatible display, used in 4-bit mode.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_lcd_hd44780_custom.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog
;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b4              -- LCD command/data select.
alias lcd_rs_direction is pin_b4_direction
alias lcd_en           is pin_b0              -- LCD data trigger
alias lcd_en_direction is pin_b0_direction

alias lcd_dataport is porta_low              -- LCD data  port
alias lcd_dataport_direction is porta_low_direction
const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line
;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction

include delay
enable_digital_io()
led_direction = output

-- setup LCD
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include lcd_hd44780_4                -- LCD library with 4 data lines
lcd_init()                           -- initialize LCD

-- ----------------------------------------------------------------------------
-- Define two custom characters.
-- a 1 makes a pixel dark ; only lower 5 bits are meaningfull (5x7 + underscore)
-- ----------------------------------------------------------------------------
const byte heat[] =
{  0b_00001001,
   0b_00001001,
   0b_00010010,
   0b_00010010,
   0b_00001001,
   0b_00001001,
   0b_00000000,
   0b_00011111
}

const byte ant[] =
{  0b_00000100,
   0b_00010101,
   0b_00001110,
   0b_00000100,
   0b_00000100,
   0b_00000100,
   0b_00000100,
   0b_00000000
}

-- ----------------------------------------------------------------------------
-- Load custom characters.
-- ----------------------------------------------------------------------------
-- This must be defined after initialization of lcd and remains in memory
-- until powerdown. 8 first characters of lcd ram are available (0-7) for
-- custom chars
-- ----------------------------------------------------------------------------
lcd_define(0, heat)
lcd_define(1, ant)

forever loop                         -- loop forever

   lcd = 0     -- display first custom character on screen
   lcd = 0     -- display a second instance of the first custom char on screen
   lcd = 0     -- display a third instance of the first custom char on screen
   lcd = "+"   -- display a + sign
   lcd = 1     -- prints second custom character on screen
   lcd = 1     -- again...
   lcd = " "   -- display a space

   LED = on
   delay_100ms(2)
   LED = off
   delay_100ms(2)

end loop

Generated by JALlib CHM Help System | Source: lcd_hd44780_common.jal


lcd_dog_m_4.jal - JALLIB Library Documentation

lcd_dog_m_4.jal JALLIB LIBRARY

Title

control for DOG-M (ST7036 based) LCD's

Author

Richard Zengerink, Copyright (c) 2008, all rights reserved, Adapted-by:

Compiler

=2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Simple interface for DOG-M (st7036) alphanumeric LCD screens.
Screens can range from 1x8 (1 lines, 8 chars), 2x16 and 3x16.
Uses 4 bit wide datapath + 2 handshake lines (total 6 PIC pins).
Expects: - 2 pins for handshake: 'lcd_rs' and 'lcd_en'
- 1 port nibble for data: 'lcd_dataport'
.
Directions for use of this library in application programs
(in this sequence):
1. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 3 lines
const byte LCD_CHARS = 16 -- 8, 16 chars per line
and variables (aliases):
var byte lcd_dataport is portA_low -- 4 data pins
var bit lcd_en is pin_A4 -- trigger
var bit lcd_rs is pin_A5 -- cmd/data select
2. Include this library.
and somewhere before actually using the lcd:
3. Set the chosen LCD dataport and handshake pins to output:
portA_low_direction = all_output
pin_A4_direction = output
pin_A5_direction = output
4. Call lcd_init() to initialize the lcd controller.
Above is an example for a 2x16 LCD:
Bits 0..3 of portA are used for data, pins 4 and 5 of portA are
used for handshake. Any other available nibble and handshake pins
could be used (provided these are configurable for output).
.
Available functions for application programs:
.
__lcd_write(<byte>) sends byte from value to
register of the lcd and
shift cursor position 1 right
.
_lcd_write_data(<byte>) write data to lcd using
__lcd_write(<byte>) lcd_rs high
.
_lcd_write_data(<byte>) write command to lcd using
__lcd_write(<byte>) lcd_rs low
.
lcd_init() initialize the LCD controller
Dependencies: delay.jal

Notes

this type can be attached to your microcontroller serial with only 3 or
4 lines in total
example type name: EA DOG-M http://www.lcd-module.com/products/dog.html
-----------------------------------------------------------------------------

Routines

  • __lcd_write - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_init - Procedure


lcd_dog_m_8.jal - JALLIB Library Documentation

lcd_dog_m_8.jal JALLIB LIBRARY

Title

control for DOG-M (ST7036 based) LCD's

Author

Richard Zengerink, Copyright (c) 2008, all rights reserved, Adapted-by:

Compiler

=2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Simple interface for DOG-M (st7036) alphanumeric LCD screens.
Screens can range from 1x8 (1 lines, 8 chars), 2x16 and 3x16.
Uses 8 bit wide datapath + 2 handshake lines (total 10 PIC pins).
Expects: - 2 pins for handshake: 'lcd_rs' and 'lcd_en'
- 1 port for data: 'lcd_dataport'
*
Directions for use of this library in application programs
(in this sequence):
1. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 3 lines
const byte LCD_CHARS = 16 -- 8, 16 chars per line
and variables (aliases):
var byte lcd_dataport is portA -- 8 data pins
var bit lcd_en is pin_b0 -- trigger
var bit lcd_rs is pin_b1 -- cmd/data select
2. Include this library.
and somewhere before actually using the lcd:
3. Set the chosen LCD dataport and handshake pins to output:
portA_direction = all_output
pin_b0_direction = output
pin_b0_direction = output
4. Call lcd_init() to initialize the lcd controller.
Above is an example for a 2x16 LCD:
portA are is used for data, pins 0 and 1 of portB are
used for handshake. Any other available port and handshake pins
could be used (provided these are configurable for output).
.
Available functions for application programs:
.
_lcd_write(<byte>) sends byte from value to
register of the lcd and
shift cursor position 1 right
.
_lcd_write_data(<byte>) write data to lcd using
_lcd_write(<byte>) lcd_rs high
.
_lcd_write_command(<byte>) write command to lcd using
_lcd_write(<byte>) lcd_rs low
.
lcd_init() initialize the LCD controller
Dependencies: delay.jal

Notes

this type can be attached to your microcontroller serial with only 3 or
4 lines in total
example type name: EA DOG-M http://www.lcd-module.com/products/dog.html
-----------------------------------------------------------------------------

Routines

  • _lcd_write - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_init - Procedure


lcd_dog_m_spi.jal - JALLIB Library Documentation

lcd_dog_m_spi.jal JALLIB LIBRARY

Title

control for DOG-M (ST7036 based) LCD's

Author

Richard Zengerink, Copyright (c) 2008, all rights reserved, Adapted-by:

Compiler

=2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Simple interface for DOG-M (st7036) alphanumeric LCD screens.
Screens can range from 1x8 (1 lines, 8 chars), 2x16 and 3x16.
Uses spi interface SI (data line), CLK (clock) RS (register select) and
if necesery CSB (chip select) (total 4 PIC pins max.).
Expects: - 1 pin for data: 'lcd_data'
- 1 pin for clock: 'lcd_clk'
- 1 pin for register/data select: 'lcd_rs'
- 1 pin for Chip Select 'lcd_csb' (if necesery, or CSB to gnd on lcd)
- 1 var bit named not_connected to assign to lcd_csb if this pin
is connected to ground.
Directions for use of this library in application programs
(in this sequence):
1. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 3 lines
const byte LCD_CHARS = 16 -- 8, or 16 chars per line
and variables (aliases):
var bit not_connected
var bit lcd_data is pin_A0 -- 1 data pin
var bit lcd_clk is pin_A1 -- 1 data pin
var bit lcd_rs is pin_A2 -- 1 data pin
var bit lcd_csb is pin_A3 -- 1 data pin
or if csb is connected to gnd:
var bit lcd_csb is not_connected
.
2. Include this library.
and somewhere before actually using the lcd:
3. Set the chosen LCD data and control pins to output:
portA_low_direction = all_output (in above case this is OK)
OR assign each pin seperatly (when not every pin is on the same port):
pin_A0_direction = output (each pin separately assigned)
pin_A1_direction = output
pin_b0_direction = output
pin_b1_direction = output
4. Call lcd_init() to initialize the lcd controller.
Above is an example for a 2x16 LCD:
.
Available functions for application programs:
.
_lcd_write(<byte>) ends byte from value to
register of the lcd and
shift cursor position 1 right
.
_lcd_write_data(<byte>) write data to lcd using
_lcd_write(<byte>) lcd_rs high
.
_lcd_write_data(<byte>) write command to lcd using
_lcd_write(<byte>) lcd_rs low
.
lcd_init() initialize the LCD controller
Dependencies: delay.jal

Notes

this type can be attached to your microcontroller serial with only 3 or
4 lines in total
example type name: EA DOG-M http://www.lcd-module.com/products/dog.html
-----------------------------------------------------------------------------

Routines

  • _lcd_write - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_init - Procedure


lcd_dsm0822a.jal - JALLIB Library Documentation

lcd_dsm0822a.jal JALLIB LIBRARY

Title

dsm0822a - i2c star burst dispay driver

Author

Joep Suijs, Copyright (c) 2009-2010, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a i2c star burst display driver
The dm0822a is a star burst display driver with an i2c interface.
To use this library:
- setup i2c comms to the display
- include this libraray and call dsm_init()
--
Now you can use the display. A char assigned to dsm_data like:
dsm_data = "A"
is displayed on the next free location. And with
dsm_data = ASCII_CR
you start printing at the first location again.
--
The indicator fields of the display can be switched on with
dsm_set_indicator(DSM_I1)
and turned off with
dsm_clear_indicator(DSM_I1)
--
The two procedures above support the next constants:
DSM_1 : channel 1 indication
DSM_2 : channel 2 indication
DSM_3 : channel 3 indication
DSM_4 : channel 4 indication
DSM_5 : channel 5 indication
DSM_6 : channel 6 indication
DSM_I1 : left signal indication
DSM_I2 : central signal indication
DSM_I3 : right signal indication
DSM_RDS : rds indicator
DSM_TP : tp indication
DSM_TA : ta indication
DSM_OO : stereo indication
DSM_FM : fm indication
DSM_DOT : decimal point
Multiple of these constants can be OR-ed together to one parameter
--

Sources

based on C program of Michael Dworkin
Info on the display at http://hobbyelektronik.org/VB/LCD/DS/index.htm

Constants and Variables

dsm_pos - var byte = 0
dsm_indicator_cache - var word = 0

Routines

  • _dsm_write_cache - Procedure
  • dsm_clear_indicator - Procedure
  • dsm_data'put - Procedure
  • dsm_init - Procedure
  • dsm_out - Procedure
  • dsm_set_indicator - Procedure


lcd_hd44780_4.jal - JALLIB Library Documentation

lcd_hd44780_4.jal JALLIB LIBRARY

Title

LCD library for HD44780 compatible LCDs, with 4 bits wide datatransfer

Author

Rob Hamerling, Copyright (c) 2008..2009, all rights reserved., Adapted-by: Eur van Andel, Joep Suijs (refactoring),Richard Zengerink (lcd_init)

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Nibble interface for HD44780 compatible alphanumeric LCD screens.
Uses 4 bits wide datapath + 2 handshake lines (total 6 PIC pins).
Expects: 2 pins for handshake: 'lcd_rs' and 'lcd_en'
and
1 port nibble for data: 'lcd_dataport'
or
4 individual pins for data: 'lcd_d4' .. 'lcd_d7'
.
Note: a 'port nibble' (the lower or higher 4 bits of a port)
gives faster and more compact code than 4 individual pins.
.
Directions for use of this library in application programs
(in this sequence):
1. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 4 lines
const byte LCD_CHARS = 16 -- 8, 16 or 20 chars per line
and aliases for handshake lines:
alias lcd_rs is pin_A5 -- cmd/data select
alias lcd_en is pin_A4 -- trigger
and aliases for 4 data lines:
alias lcd_dataport is portA_low -- 4 databits
or
alias lcd_d4 is pin_A3 -- lcd databit d4
alias lcd_d5 is pin_A1 -- lcd databit d5
alias lcd_d6 is pin_C0 -- lcd databit d6
alias lcd_d7 is pin_C2 -- lcd databit d7
.
2. Set the chosen LCD dataport and handshake pins to output:
pin_A4_direction = output
pin_A5_direction = output
and the data port nibble to output:
portA_low_direction = all_output
or the 4 individual datapins to output:
pin_A3_direction = output
pin_A1_direction = output
pin_C0_direction = output
pin_C2_direction = output
.
3. Include this library.
.
4. Call lcd_init() to initialize the lcd controller.
.
Above is an example for a 2x16 LCD.
.
See hd_44780_common for the LCD API.
Dependencies: delay.jal
lcd_hd44780_common.jal
-----------------------------------------------------------------------------

Routines

  • __lcd_write - Procedure
  • __lcd_write_nibble - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_init - Procedure


lcd_hd44780_8.jal - JALLIB Library Documentation

lcd_hd44780_8.jal JALLIB LIBRARY

Title

LCD library for HD44780 compatible LCDs, with 8 bits wide datatransfer

Author

Rob Hamerling, Copyright (c) 2008..2009, all rights reserved., Adapted-by: Eur van Andel, Joep Suijs (refactoring),Richard Zengerink (lcd_init)

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Port interface for HD44780 compatible alphanumeric LCD screens.
Uses 8 bits wide datapath + 2 handshake lines (total 10 PIC pins).
Expects: 2 pins for handshake: 'lcd_rs' and 'lcd_en'
and:
1 complete port for data: 'lcd_dataport'
or
2 nibbles for data: 'lcd_dataport_low' and 'lcd_dataport_high'
or
8 individual pins for data: lcd_dataline_d0 .. _d7
.
note: a complete ports gives faster and more compact code then
two port 'nibble'' (the lower or higher 4 bits of a port)
which is on its turn faster than 8 individual pins.
.
Directions for use of this library in application programs
(in this sequence):
1. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 4 lines
const byte LCD_CHARS = 16 -- 8, 16 or 20 chars per line
and aliases for handshake lines:
alias lcd_rs is pin_D2 -- cmd/data select
alias lcd_en is pin_D3 -- trigger
and aliases for 8 data lines:
alias lcd_dataport is portF -- 8 databits
or
alias lcd_dataport_low is portD_high -- 4 low order databits
alias lcd_dataport_high is portC_high -- 4 high order databits
or
alias lcd_d0 is pin_D0 -- lcd databit d0
alias lcd_d1 is pin_D1 -- lcd databit d1
alias lcd_d2 is pin_C6 -- lcd databit d2
alias lcd_d3 is pin_C7 -- lcd databit d3
alias lcd_d4 is pin_B0 -- lcd databit d4
alias lcd_d5 is pin_B1 -- lcd databit d5
alias lcd_d6 is pin_C0 -- lcd databit d6
alias lcd_d7 is pin_C2 -- lcd databit d7
.
2. Set the chosen LCD handshake pins to output:
pin_D2_direction = output
pin_D3_direction = output
and the data port to output:
portF_direction = ALL_OUTPUT
or 2 data port nibbles to output:
portD_high_direction = ALL_OUTPUT
portC_high_direction = ALL_OUTPUT
or 8 individual data pins to outout:
pin_D0_direction = output
pin_D1_direction = output
pin_C6_direction = output
pin_C7_direction = output
pin_B0_direction = output
pin_B1_direction = output
pin_C0_direction = output
pin_C2_direction = output
.
3. Include this library.
.
4. Call lcd_init() to initialize the lcd controller.
.
Above is an example for a 2x16 LCD.
.
See hd_44780_common for the LCD API.
Dependencies: delay.jal
lcd_hd44780_common.jal
-----------------------------------------------------------------------------

Routines

  • __lcd_write - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_init - Procedure


lcd_hd44780_common.jal - JALLIB Library Documentation

lcd_hd44780_common.jal JALLIB LIBRARY

Title

common library for HD44780 based LCD

Author

Richard Zengerink, Copyright (c) 2008..2011, all rights reserved., Adapted-by: Joep Suijs, Rob Hamerling

Compiler

2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Common API for HD44780 based LCD

Notes

----------------------------------------------------------------------------
constants to control the lcd
----------------------------------------------------------------------------

Routines

  • _lcd_line2index - Function returns byte
  • _lcd_restore_cursor - Procedure
  • lcd'put - Procedure
  • lcd_clear_line - Procedure
  • lcd_clear_screen - Procedure
  • lcd_clearscreen - Procedure
  • lcd_cursor_blink_display - Procedure
  • lcd_cursor_position - Procedure
  • lcd_cursor_shift_left - Procedure
  • lcd_cursor_shift_right - Procedure
  • lcd_define - Procedure
  • lcd_home - Procedure
  • lcd_progress - Procedure
  • lcd_shift_left - Procedure
  • lcd_shift_right - Procedure
  • lcd_write_char - Procedure
  • lcd_writechar - Procedure


lcd_hd44780_pcf8574.jal - JALLIB Library Documentation

lcd_hd44780_pcf8574.jal JALLIB LIBRARY

Title

LCD library for HD44780 compatible LCDs, interfaced with pcf8574

Author

Joep Suijs, Copyright (c) 2011..2011, all rights reserved., Adapted-by:

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

i2c bus interface for HD44780 compatible alphanumeric LCD screens.
Tested on the DFRobot 'i2c/twi lcd 1602 module'
See bits on lcd_shadow for the connection from the pcf8574 to the LCD.
--
Directions for use of this library in application programs
(in this sequence):
1. Setup i2c master (include i2c_hardware or include i2c_software)
--
2. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 4 lines
const byte LCD_CHARS = 16 -- 8, 16 or 20 chars per line
--
3. Include this library.
--
4. Call lcd_init() to initialize the lcd controller.
--
Above is an example for a 2x16 LCD, connected to pin d0
--
See hd_44780_common for the LCD API.
Dependencies: delay.jal
i2c
lcd_interface.jal - the application that converts serial to the LCD interface
-----------------------------------------------------------------------------

Constants and Variables

lcd_shadow - var byte

Routines

  • __lcd_write - Procedure
  • __lcd_write_nibble - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_backlight - Procedure
  • lcd_backlight_variable - Procedure
  • lcd_init - Procedure
  • write_lcd_shadow - Procedure


lcd_hd44780_serial_sw.jal - JALLIB Library Documentation

lcd_hd44780_serial_sw.jal JALLIB LIBRARY

Title

LCD library for HD44780 compatible LCDs, interfaced with 1 pin (serial_sw)

Author

Joep Suijs, Copyright (c) 2008..2009, all rights reserved., Adapted-by: Richard Zengerink (lcd_init)

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Software serial interface for HD44780 compatible alphanumeric LCD screens.
--
Directions for use of this library in application programs
(in this sequence):
1. Declare the following constants:
const byte LCD_ROWS = 2 -- 1, 2 or 4 lines
const byte LCD_CHARS = 16 -- 8, 16 or 20 chars per line
and variables (aliases):
var bit serial_sw_tx_pin is pin_d0 -- pin on which lcd is connected
--
2. Set the chosen LCD dataport and handshake pins to output:
pin_d0_direction = output
--
3. Include this library.
--
4. Call lcd_init() to initialize the lcd controller.
--
Above is an example for a 2x16 LCD, connected to pin d0
--
See hd_44780_common for the LCD API.
Dependencies: delay.jal
serial_software
lcd_interface.jal - the application that converts serial to the LCD interface
-----------------------------------------------------------------------------

Constants and Variables

serial_sw_invert - const bit = true ; normal (low active) serial comms
lcd_rs_shadow - var bit

Routines

  • __lcd_write - Procedure
  • __lcd_write_nibble - Procedure
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • lcd_backlight - Procedure
  • lcd_backlight_variable - Procedure
  • lcd_init - Procedure


lcd_home - JALlib Procedures Help

lcd_home JALLIB PROCEDURE

Signature

procedure lcd_home() is

Description

lcd_home - cursor returns home(line 0, position 0)

Include

To use this procedure, include the library:

include lcd_hd44780_common

Parameters

None

Return Value

None

Example

From sample file: 18f2585_can_serial_adapter.jal

-- Title: CAN bus translator from 3 wire CAN bus to RS232
-- Author: William Welch Copyright (c) 2009, all rights reserved.
-- Adapted by: Eur van Andel, eur@fiwihex.nl, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: -- Implements bridge/gateway between RS232 and CAN bus.
--
-- This file has been generated by hand (manually maintained)
--

const byte version_h = 1
const byte version_l = 04

const serial_hw_baudrate = 57600
-- const serial_hw_baudrate = 115200

include 18f2585
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = off                          -- no watchdog

include delay
include format
include print

const byte banner[] = "Bus translator"
const byte baudstr[] = " baud"

enable_digital_io()

const down  = 0
const green = 1
const red   = 2

var bit led      is pin_b1
var bit led_dir  is pin_b1_direction

led_dir = input
led = low

procedure leds(byte in x) is
   if x == down then
      led_dir  = input
   elsif x == red then
      led_dir  = output
      led      = low
   elsif x == green then
      led_dir  = output
      led     = high
   end if
end procedure

var bit toggle

const byte LCD_ROWS = 4
const byte LCD_CHARS = 20
var bit lcd_sterm_pin is pin_C0
var bit lcd_sterm_pin_dir is pin_C0_direction
include lcd_sterm_master

const usart_hw_serial = true
var bit serial_ctsinv
var  bit serial_overflow_discard = false
include serial_hw_int_cts
serial_hw_init()

-- ECAN controller is built-in to 18F2585
-- but we will operate in 'legacy' mode 0.
pin_B2 = high -- set CANTX high for recessive level
pin_B2_direction = output
pin_B3_direction = input
include can_legacy
include can_ascii

can_reset()

-- FIXME: use EEprom instead.
-- 125K bps
can_set_config(4, 0x9E, 3)
CIOCON = 0x20; -- TXCAN, high when recessive

-- in this example we combine the hardware buffers.
RXB0CON = 0x04 -- rollover/ double-buffer
RXB1CON = 0x00 -- all valid frames go to buffer #1.

-- FIXME: use EEprom instead.
-- RXB0 will match all msgs by default
can_set_rxb0_mask(0,0,0,0)
can_set_rxb0_filter0(0xff, 0xff, 0xff, 0xff)
can_set_rxb0_filter1(0xff, 0xff, 0xff, 0xff)

-- disable RXB1
can_set_rxb1_mask(0xff,0xff,0xff,0xff)
can_set_rxb1_filter2(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter3(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter4(0xff, 0xff, 0xff, 0xff)
can_set_rxb1_filter5(0xff, 0xff, 0xff, 0xff)

TXB0CON = 0;
TXB1CON = 0;
TXB2CON = 0;

CANCON = 0; -- normal mode

include can_adapter

-- start of procedure block --------------------------------------------------

procedure pdec8(volatile byte out device, byte in n) is
   device = "0" + n / 100
   n = n % 100

   device = "0" + n / 10
   n = n % 10

   device = "0" + n
end procedure

-- end of procedure block --------------------------------------------------

-- wait for STERM Slave to power-up and initialize.
for 10 loop
   leds(green)
   delay_100ms(2)
   leds(red)
   delay_100ms(2)
end loop
leds(down)

lcd_home()
lcd_clear_screen()
lcd_home()
print_string(lcd, banner)
const byte str2[]="Version "
lcd_cursor_position(2,0)
print_string(lcd, str2)
pdec8(lcd,version_h)
lcd = "."
pdec8(lcd,version_l)
lcd_cursor_position(3,0)
print_word_dec(lcd, serial_hw_baudrate)
print_string(lcd, baudstr)

-- leave banner up for a while
for 25 loop
   leds(green)
   delay_100ms(2)
   leds(down)
   delay_100ms(2)
end loop

-- monitor loop
forever loop
   var bit got_ch, got_msg
   var byte ch,i,len
   var byte rxdata[8]
   var dword can_id

   -- check for a msg from PC/UART
   got_ch = serial_hw_read(ch)
   while got_ch loop
      can_check_uart_rx(serial_hw_data, ch)
      got_ch = serial_hw_read(ch)
   end loop

   -- check for CAN message and handle it.
   got_msg = can_check_can_rx(serial_hw_data, can_id, rxdata, len)

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

   delay_100ms(1) -- slow down blinking leds
end loop

Generated by JALlib CHM Help System | Source: lcd_hd44780_common.jal


lcd_init - JALlib Procedures Help

lcd_init JALLIB PROCEDURE

Signature

procedure lcd_init() is

Description

Send reset to Terminal:
Clear the LCD and makes a sw reset of the PIC.

Include

To use this procedure, include the library:

include lcd_sterm_master

Parameters

None

Return Value

None

Example

From sample file: 16f876a_co2_t6603.jal

-- Title: read CO2 values from GE/Telaire T6603 CO2 sensor, show on LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read CO2 concentration values
-- from the GE/Telaire CO2 sensor, using the serial_hardware, delay
-- and t6603_co2 library. It uses a 4x20 LCD for user interaction.
-- The T6603 uses 3.3V serial signals, negative logic at 19k2 baud.
-- Use a level converter like the 74xx07 with both 5V and 3.3V pullups.
--
-- This file has been generated by hand (manually maintained)
--
-- Note: the CO2 sensor needs some 20s to get heated after powerup. Just wait.
-- The sensor sometimes gives a wrong value, this is just after it
-- updates the internal value. This can be overcome by polling the status byte
-- until it is non-zero, then waiting for a second before polling the ppm value.
-- This is not done here.

const version_h = 0
const version_l = 4

-- select PIC
include 16f876a

pragma target clock     20_000_000     -- 20 MHz xtal
pragma target OSC    HS
pragma target WDT    disabled    -- no watchdog, please
pragma target LVP    enabled     -- allow low voltage programming, frees up pin_b3

-- set all IO as digital
enable_digital_io()

-- ------------------- INCLUDE LIBRARIES --------------------------

const usart_hw_serial      = true   -- true = RS232, false = SPI
const serial_hw_baudrate   = 19_200
include serial_hardware
serial_hw_init()           -- calculate baudrate, turn peripheral on

const byte LCD_CHARS = 20
const byte  LCD_ROWS = 4

alias LCD_RS           is pin_b5       -- LCD command/data select.
alias LCD_EN           is pin_b4       -- LCD data trigger
alias LCD_dataport     is portb_low    -- LCD data nibble
portb_direction        = all_output    -- LCD data is portb_low
include lcd_hd44780_4                  -- LCD library with 4 data lines
lcd_init()

include print                          -- nice formatted output

delay_100ms(5)                      -- to get the LCD up & running

include co2_t6603                      -- actual CO2 library

-- ---------------- VARIABLES ---------------------------

var word co2                  -- in ppm

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
lcd_cursor_position(0,0)
const byte str1[] = "sample T6603 CO2"
print_string(lcd, str1)               -- output string to LCD
lcd_cursor_position(1,0)              -- second line of display

forever loop

   CO2 = get_co2_ppm()
   lcd_cursor_position(1, 0)             -- row 2,
   print_word_dec(lcd, CO2)
   lcd="p" lcd="p" lcd="m" lcd =" " lcd =" " lcd =" "

   delay_100ms(10)                  -- don't poll sensor too often

end loop

Generated by JALlib CHM Help System | Source: lcd_sterm_master.jal


lcd_one_dot_matrix.jal - JALLIB Library Documentation

lcd_one_dot_matrix.jal JALLIB LIBRARY

Title

LCD library for LCDs with just one big dot matrix for use as simple character device

Author

Pavel Milanes Costa, Copyright (c) 2015, all rights reserved. pavelmc@gmail.com, Adapted-by:

Compiler

>=2.4p3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This modules have the (same) following pinouts:
--
1 GND Ground or 0.0 volts
2 VDD (2.7 to 5.5 V)
3 VEE (-1.0 to -2.3V) This is used for display contrast, see datasheet !!!
4 A0 Instruction (off) / Data (on) selector
5 R/W Read/Write, tie it to GND, this lib doesn't read.
6 E3 Enable chip 3
7 D0 bit 0 data
8 D1 bit 1 data
9 D2 bit 2 data
10 D3 bit 3 data
11 D4 bit 4 data
12 D5 bit 5 data
13 D6 bit 6 data
14 D7 bit 7 data
15 LED K Backlight Led Cathode (hole, but no pin on)
16 LED A Backlight Led Anode (hole, but no pin on)
17 E1 Enable chip 1
18 E2 Enable chip 2
--
This LCD need 12 pins from your PIC and will eat about ~1k more of your memory over
the classic lcd library, plus some data banks, and only implement charcater capability
no graphs here.
--
As per the datasheet the command set of this lib is compatible with this chips:
AX6120, AX6121, SBN1661, SBN0080, SED1520, SED1521 and SED1522
others can be supported.
--
You must define a full 8 bit dataport for data communication
--
alias lcd_dataport is portB
--
Also need to define the handshake and enable pins
--
alias lcd_a0 is pin_C0
alias lcd_e1 is pin_C1
alias lcd_e2 is pin_C2
alias lcd_e3 is pin_C3
--
You need to set all this pins/ports to 'output' direction
--
This lib asume your hardware use 3 chips to manage the 160 columns in a 40+80+40 splits,
then, when used in character mode (not graphics) you can use a 26x4 area (pretty good!!!)
so this size is hard coded on the lib code. If your hardware use other split or size
of the matrix: copy this file, adapt it, create another lib and submmit it to jallib project
--
Then include the library
--
include lcd_one_dot_matrix.jal
--
Call the init of the lib and you are rocking now
--
lcd_init()
Note: This lib doesn't read anything from the LCD, the lcd has this capability, but it will eat
one of your precious pins and more code area; we manage to wait the time stated on the
datasheets to not get caught in a busy state when writing.
--
This lib use the data port ONLY when writing to it, so the rest of the time it's on input
mode and you can use this port as you like, so you can play with it to multiplex a function
on this data port.
Dependencies: delay.jal, lcd_5x7_font.jal

compiler sanity checks
ERROR
ERROR
ERROR

Sources

Datasheets of two type of GLCD modules & dot matrix controllers
- DATA IMAGE PY163210 REV:A (thanks to sally Kao at DATA IMAGE enterprise)
- XIAMEN OCULAR GDM16032D VER1.0 (from website)
- Datasheets for the SBN1661, AX6120 and SED1520 dot matrix LCD controllers
--
As usual nowdays, a variety of sources on the internet...

Routines

  • _lcd_on - Procedure
  • _lcd_send_cmd - Procedure
  • _lcd_set_column - Procedure
  • _lcd_set_page - Procedure
  • _lcd_write - Procedure
  • lcd'put - Procedure
  • lcd_clear_row - Procedure
  • lcd_clear_screen - Procedure
  • lcd_cursor_position - Procedure
  • lcd_init - Procedure
  • lcd_write_char - Procedure


lcd_sterm_master.jal - JALLIB Library Documentation

lcd_sterm_master.jal JALLIB LIBRARY

Title

STERM Master library for JALLIB

Author

Javier Martnez & Eur Van Andel Copyright (C) 2003-2009 All rights reserved, Adapted-by: William Welch

Compiler

2.4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html) This file is part of jallib (https://github.com/jallib/jallib)

Description

Sterm (Serial Terminal) is a protocol to write to an standard HD44780 LCD
and read from a 4x4 matrix keyboard. It was developed for easy debugging of JAL programs.
With Sterm and a single PIC pin you can do a lot of human interfacing, often to the point that
nothing else is needed. Especially usefull for projects "beyond the PC", that have to work in the field.
Note: as of oct 4, 2009 the slave code has to be upgraded to JALV2 as well, and posted with the schematics.
Expects: a single pin, with sterm_pin as variable and sterm_dir as direction, like this:
var bit sterm_pin is pin_A4
var bit sterm_dir is pin_A4_direction
since the traffic on this pin is bidirectional, the pin needs to be protected on both sides:
-+---------+ +5V
| |
.-. |
| |10k |
| | |
'-' +--o Sterm connector
| ___
o------+-|___|------o Sterm connector
PIC pin 330
+--o Sterm connector
|
|
GND
Obviously, Sterm needs +5V and GND as well. The 10k pull-up resistor defines the pin state
when nothing is connected and the 330 Ohm resistor protects against too much current, for instance when
master and slave talk at the same time.
Master Serial Terminal routines

Frame structure
+---+---------+------+
| S | command | data |
+---+---------+------+
S = Sync bit, active low.
command = ( 4 bits )
M->S 0x00 Output STerm flags.
0x01 Output data is 'LCD instruction'.
0x02 Output data is 'LCD data'.
0x03 Output data is serial data to PC.
0x04 Reserved (not used yet).
0x05 Reserved (not used yet).
0x06 Reserved (not used yet).
0x07 Reserved (not used yet).

S->M 0x08 Input STerm flags.
0x09 Input data is keyboard.
0x0A Input data is serial data from PC.
0x0B Input data is serial buffer status.
0x0C Reserved (not used yet).
0x0D Reserved (not used yet).
0x0E Reserved (not used yet).
0x0F Reserved (not used yet).
data = ( 8 bits )
STerm Flags
Write with command 0x00, read with command 0x08.
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| | | | | | | | R |
+---+---+---+---+---+---+---+---+
R = Reset STerm (Active High).

Constants and Variables

lastkey - var byte = 0xff

Routines

  • __term_byte - Function returns byte
  • _lcd_write_command - Procedure
  • _lcd_write_data - Procedure
  • getkey - Function returns byte
  • getkey_once - Function returns byte
  • lcd_buflag - Function returns byte
  • lcd_init - Procedure
  • lcd_key'get - Function returns byte


lcd_write_char - JALlib Procedures Help

lcd_write_char JALLIB PROCEDURE

Signature

procedure lcd_write_char(byte in data) is

Description

lcd_write_char - write one char to LCD

Include

To use this procedure, include the library:

include lcd_hd44780_common

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 16f887_lcd_hd44780_4_1.jal

-- ------------------------------------------------------
-- Title: LCD sample program for the Microchip PIC 16f887
--
-- Author: Rob Hamerling, Copyright (c) 2009..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    LCD sample program for Microchip PIC 16f887.
--    Shows some texts on a 2 x 16 LCD display.
--    Blinks also a LED on pin_A0 to show program is running.
--    Uses:  - LCD library lcd_hd44780_4.jal
--           - 4 LCD data lines
--           - DataPath: 4 individual bits
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 14 Mar 2014 16:31:14
--  - This file is generated by script "lcd-sample.cmd"
--    and a table "lcd-sample.lst".  Do not change!
--
-- ------------------------------------------------------
--
include 16f887                       -- target PICmicro
--
-- This program assumes that 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      CONTROL      -- watchdog
pragma target LVP  enabled            -- allow low voltage programming
pragma target MCLR external
WDTCON_SWDTEN = OFF                 -- disable WDT
--
enable_digital_io()                   -- disable analog I/O (if any)
--
pin_A0_direction       =  output      -- blinking LED
--
const byte LCD_ROWS    =  2           -- LCD with 2 lines
const byte LCD_CHARS   =  16          -- and 16 characters per line
--
alias     lcd_en       is pin_D3      -- data trigger
alias     lcd_rs       is pin_D2      -- command/data select.
pin_D3_direction       = output
pin_D2_direction       = output
--
alias     lcd_d4       is pin_D4
alias     lcd_d5       is pin_D5
alias     lcd_d6       is pin_D6
alias     lcd_d7       is pin_D7
--
pin_D4_direction       = output
pin_D5_direction       = output
pin_D6_direction       = output
pin_D7_direction       = output
--
include lcd_hd44780_4
--
lcd_init()                            -- init the lcd controller
--
include delay                         -- fetch delay library
--
-- --- generate LCD screen activity ---------
var byte line1[LCD_CHARS] = "<= 2 x 16 LCD =>"
var byte line2[LCD_CHARS] = "0123456789ABCDEF"
var byte i, k
forever loop
   lcd_clear_screen()             -- (to first line)
   delay_100ms(5)
   for LCD_CHARS using i loop
      lcd_write_char(line1[i])    -- write using procedure
   end loop
   delay_100ms(5)
   lcd_cursor_position(1,0)       -- to second line
   for LCD_CHARS using i loop
      k = (i * 7) & 0x0F          -- "random" character(index)
      lcd_cursor_position(1,k)    -- corresponding position
      lcd = line2[k]              -- write using pseudo variable
      delay_100ms(3)              -- pause between bytes
      pin_A0 = !pin_A0            -- flip the LED
   end loop
   delay_100ms(10)
end loop
--

Generated by JALlib CHM Help System | Source: lcd_hd44780_common.jal


lolfont1.jal - JALLIB Library Documentation

lolfont1.jal JALLIB LIBRARY

Title

US ASCII proportional font for the 9x14 LoL shield.

Author

Rob Hamerling.

Compiler

2.4q3

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

Font for LoL shield.
This is basically a 5x7 font (width x height),
but proportional: characters can be wider, narrower or lower!
The upper line of the LoL shield is currently not used, the
lower line is used for descenders (like for g,j,p,q, underscore).
Supported ASCII value range: 32..126, characters outside
this range are displayed as a large rectangular.
The characters in the font table are right aligned and
mirrored because the low order bits represent the leftmost
leds of the shield.
The width of a character can be determined by the user program
(at compiletime or runtime) as follows:
Take the maximum value of the lines of a character and round it
to the next power of 2. This power is the character width.
For example: of character '7' the highest value is 0x1F (31),
The next power of 2 is 2^5 (32), thus '7' is 5 colums wide.

Notes

- This font table is a single array of 96 x 9 words
and may work only with 18F type PICs.
- See Jallib 'lolshield_ticker1' samples for usage.


lolfont.jal - JALLIB Library Documentation

lolfont.jal JALLIB LIBRARY

Title

US ASCII proportional font for the 9x14 LoL shield.

Author

Rob Hamerling.

Compiler

2.4q3

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

Font for LoL shield.
This is basically a 5x7 font (width x height),
but proportional: characters can be wider, narrower or lower!
The upper line of the LoL shield is currently not used, the
lower line is used for descenders (like for g,j,p,q, underscore).
Supported ASCII value range: 32..126, characters outside
this range are displayed as a solid block.
The characters in the font table are right aligned, and
mirrored because the low order bits represent the leftmost
leds of the shield.
The width of a character can be determined by the user program
(at compiletime or runtime) as follows:
Take the maximum value of the lines of a character and round it
to the next power of 2. This power is the character width.
For example: of character '7' the highest value is 0x1F (31),
The next power of 2 is 2^5 (32), thus '7' is 5 colums wide.

Notes

- This font table is splitted into nine separate arrays
(one per row) to overcome memory limitations of JalV2.
- See Jallib 'lolshield_ticker' samples for usage.


LOOP - JAL Language Syntax Reference

LOOP JALV2 SYNTAX

Syntax

LOOP
    statement_block
END LOOP

Description

The LOOP construct is used to create iterative structures in JAL. It can be combined with different control statements to create various types of loops:

Notes

All loop types support the EXIT LOOP statement to terminate the loop early. The loop body must be terminated with END LOOP.

Example

-- Simple FOR loop
FOR 10 LOOP
    serial_hw_data = "Hello"
END LOOP

-- WHILE loop with condition
WHILE counter < 100 LOOP
    counter = counter + 1
    IF counter == 50 THEN
        EXIT LOOP
    END IF
END LOOP

-- FOREVER loop (main program loop)
FOREVER LOOP
    process_input()
    update_display()
END LOOP

Generated by JAL Syntax Documentation System | Source: DITA


ls7366r_init - JALlib Procedures Help

ls7366r_init JALLIB PROCEDURE

Signature

procedure ls7366r_init() is

Description

Initialize

Include

To use this procedure, include the library:

include quadrature_counter_ls7366r

Parameters

None

Return Value

None

Example

From sample file: 18f4620_quadrature_counter_ls7366r.jal

-- Title: Quadrature Counter ls7366r
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler:2.4q6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: ls7366r is a quadrature encoder counter for counting or
--              keeping track of the position of a optical rotary encoder
--              or linear slide. This device can count signals of TTL type
--              (pulses 90 degrees out of phase) or signals with
--              up/down direction and clock signals. TTL mode is default
--              in this lib.
--
-- Notes:
--     Use ls7366r_write(WRITE_MDR0, 0x00) after init() for
--     devices with up/down direction and count clock outputs (not tested).
--
-- Sources:
-- https://lsicsi.com/datasheets/LS7366R.pdf
--
-- This file has been manually generated.
--

include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a0
alias led_direction is pin_a0_direction
led_direction = output

-- setup ls7366r
-- setup spi chip select pin
ALIAS ls7366r_chip_select             is pin_ss
ALIAS ls7366r_chip_select_direction   is pin_ss_direction
-- initial settings
ls7366r_chip_select_direction = output -- chip select/slave select pin
ls7366r_chip_select = high             -- start chip slect high (chip disabled)
alias ls7366r_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
-- Include and init
include quadrature_counter_ls7366r
ls7366r_init()
;ls7366r_write(WRITE_MDR0, 0x00) -- for devices with up/down direction and clock signals

-- Test communication
if ls7366r_read(LS7366R_READ_MDR0) == 3 then ;read what was set in init procedure
   print_string(serial_data,"LS7366R Loaded OK")
else
   print_string(serial_data,"LS7366R communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   -- Report current count/position
   print_dword_dec(serial_data,ls7366r_read_counter())
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: quadrature_counter_ls7366r.jal


ls7366r_read - JALlib Procedures Help

ls7366r_read JALLIB FUNCTION

Signature

function ls7366r_read(byte in op_code) return byte is

Description

Read one byte

Include

To use this procedure, include the library:

include quadrature_counter_ls7366r

Parameters

  • op_code - byte in

Return Value

byte - Function return value

Example

From sample file: 18f4620_quadrature_counter_ls7366r.jal

-- Title: Quadrature Counter ls7366r
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler:2.4q6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: ls7366r is a quadrature encoder counter for counting or
--              keeping track of the position of a optical rotary encoder
--              or linear slide. This device can count signals of TTL type
--              (pulses 90 degrees out of phase) or signals with
--              up/down direction and clock signals. TTL mode is default
--              in this lib.
--
-- Notes:
--     Use ls7366r_write(WRITE_MDR0, 0x00) after init() for
--     devices with up/down direction and count clock outputs (not tested).
--
-- Sources:
-- https://lsicsi.com/datasheets/LS7366R.pdf
--
-- This file has been manually generated.
--

include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a0
alias led_direction is pin_a0_direction
led_direction = output

-- setup ls7366r
-- setup spi chip select pin
ALIAS ls7366r_chip_select             is pin_ss
ALIAS ls7366r_chip_select_direction   is pin_ss_direction
-- initial settings
ls7366r_chip_select_direction = output -- chip select/slave select pin
ls7366r_chip_select = high             -- start chip slect high (chip disabled)
alias ls7366r_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
-- Include and init
include quadrature_counter_ls7366r
ls7366r_init()
;ls7366r_write(WRITE_MDR0, 0x00) -- for devices with up/down direction and clock signals

-- Test communication
if ls7366r_read(LS7366R_READ_MDR0) == 3 then ;read what was set in init procedure
   print_string(serial_data,"LS7366R Loaded OK")
else
   print_string(serial_data,"LS7366R communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   -- Report current count/position
   print_dword_dec(serial_data,ls7366r_read_counter())
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: quadrature_counter_ls7366r.jal


ls7366r_write - JALlib Procedures Help

ls7366r_write JALLIB PROCEDURE

Signature

procedure ls7366r_write(byte in op_code, byte in data) is

Description

Write one byte

Include

To use this procedure, include the library:

include quadrature_counter_ls7366r

Parameters

  • op_code - byte in
  • data - byte in

Return Value

None

Example

From sample file: 18f4620_quadrature_counter_ls7366r.jal

-- Title: Quadrature Counter ls7366r
-- Author: Matthew Schinkel, copyright (c) 2017, all rights reserved.
-- Adapted-by:
-- Compiler:2.4q6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: ls7366r is a quadrature encoder counter for counting or
--              keeping track of the position of a optical rotary encoder
--              or linear slide. This device can count signals of TTL type
--              (pulses 90 degrees out of phase) or signals with
--              up/down direction and clock signals. TTL mode is default
--              in this lib.
--
-- Notes:
--     Use ls7366r_write(WRITE_MDR0, 0x00) after init() for
--     devices with up/down direction and count clock outputs (not tested).
--
-- Sources:
-- https://lsicsi.com/datasheets/LS7366R.pdf
--
-- This file has been manually generated.
--

include 18f4620                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- do not use extended instructionset
pragma target DEBUG    DISABLED                  -- no debugging
pragma target BROWNOUT DISABLED                  -- no brownout reset
pragma target FCMEN    DISABLED                  -- no clock monitoring
pragma target IESO     DISABLED                  -- no int/ext osc switching
pragma target LVP      ENABLED                   -- allow low voltage programming
pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = FALSE               -- no PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
include print
include format
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_64) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- led
alias led           is pin_a0
alias led_direction is pin_a0_direction
led_direction = output

-- setup ls7366r
-- setup spi chip select pin
ALIAS ls7366r_chip_select             is pin_ss
ALIAS ls7366r_chip_select_direction   is pin_ss_direction
-- initial settings
ls7366r_chip_select_direction = output -- chip select/slave select pin
ls7366r_chip_select = high             -- start chip slect high (chip disabled)
alias ls7366r_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
-- Include and init
include quadrature_counter_ls7366r
ls7366r_init()
;ls7366r_write(WRITE_MDR0, 0x00) -- for devices with up/down direction and clock signals

-- Test communication
if ls7366r_read(LS7366R_READ_MDR0) == 3 then ;read what was set in init procedure
   print_string(serial_data,"LS7366R Loaded OK")
else
   print_string(serial_data,"LS7366R communication failed")
end if
print_crlf(serial_data)

-- main program
forever loop
   led = !led
   _usec_delay(250_000)

   -- Report current count/position
   print_dword_dec(serial_data,ls7366r_read_counter())
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: quadrature_counter_ls7366r.jal


ltc2942.jal - JALLIB Library Documentation

ltc2942.jal JALLIB LIBRARY

Title

LTC2942 I2C battery gas gauge with temperature and voltage measurement

Author

Bogdan Mihai Octavian, NO copyright....use it or loose it!

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

I2C read, write, conversion to decimal(mAh, mV, Celsius degrees), ARA response routines.
I2C 1 cell LiFePO4/LiPo gas gauge (capacity) / Coulomb counter with programmable alarms
This library contains the basic routines to build a battery gas gauge
Capacity is calculated with prescaler M set to 1:128 and Rsense resistor of 25 miliOhms (0R025) !!!!
Voltage and temperature routines works independently of battery capacity.
Please read the datasheet for a better understanding !!!
DATASHEET : http://cds.linear.com/docs/en/datasheet/2942fa.pdf
Some LTC2942 registers
00h "A" register = STATUS (R)
01h "B" register = CONTROL (R/W)
02h "C" register = ACR MSB (R/W) Accumulated charge
03h "D" register = ACR LSB (R/W)
04h "E" register = CTH MSB (R/W) Charge Threshold High
05h "F" register = CTH LSB (R/W)
06h "G" register = CTL MSB (R/W) Charge Threshold Low
07h "H" register = CTL LSB (R/W)
08h "I" register = VOLTAGE MSB (R)
09h "J" register = VOLTAGE LSB (R)
0Ah "K" register = VTH (R/W) Voltage Threshold High
0Bh "L" register = VTL (R/W) Voltage Threshold LOW
0Ch "M" register = Temp. MSB (R) Temperature on chip
0Dh "N" register = Temp. LSB (R)
0Eh "O" register = TTH (R/W) Temperature Threshold High
0Fh "P" register = TTL (R/W) Temperature Threshold Low
STATUS:
b7 = Chip ID (0 = 2942 / 1 = 2941)
b6 = reserved
b5 = ACR Over/Under flow (1 = TRUE)
b4 = Temp. alert (1 = TRUE)
b3 = Charge alert high (1 = TRUE)
b2 = Charge alert low (1 = TRUE)
b1 = Voltage alert (1 = voltage limits exceeded)
b0 = UnderVoltage Lockout alert (1 = UVLO has occured)
CONTROL:
b7:b6 = ADC mode -- default
b5:b3 = Prescaler M (111 = default)
b2:b1 = AL/CC configure (10 = ALERT = default / 11 = NOT allowed)
b0 = shutdown analog section (1 = TRUE)

----------------------------------------------------------------------------
reading registers
------------------------------------------------------------------------------

Routines

  • lrc2942_acr_read - Function returns word
  • ltc2942_ara - Function returns bit
  • ltc2942_control'get - Function returns byte
  • ltc2942_control'put - Procedure
  • ltc2942_read - Procedure
  • ltc2942_status'get - Function returns byte
  • ltc2942_temperature - Function returns byte
  • ltc2942_voltage - Function returns word
  • ltc2942_write - Procedure


math.jal - JALLIB Library Documentation

math.jal JALLIB LIBRARY

Title

Calculate the square root of an unsigned 16-bits integer

Author

Rob Hamerling, Michael Watterson Copyright (c) 2009..2011, all rights reserved., Adapted-by: Michael Watterson, Eur van Andel, Rob Hamerling

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Collection of mathematical routines.

Notes

.
1. This library contains a number of routines handling 'fixed point' numbers.
These numbers are contained in a signed word or signed double word
as <value> * 256. In other words the digits behind the decimal point are
stored in the least significant byte of the signed word or signed double word.
For example a fixed point value '+18.5' is stored in a 16-bits signed word
with value 256 * 18.5, which is 4736 decimal or 0x1280 hexadecimal.
You could also think of '+18' (0x12) being stored in the most significant byte
and '.5' in the least significant byte (0.5 * 256 = 128, or 0x80).
2. Fixed point math is 8 bits for the decimal part in this library,
approximately 2 decimal places, the part after the "point" is 0 to 255.
sword fixed point numbers are thus -127.00 to +127.00 approx.
When you need bigger numbers replace all swords by sdwords and
sdwords by sbyte*8, if the compiler can still do the math.

--------------------------------------------------------------

Sources

Various authors.

Routines

  • abs16 - Function returns word
  • abs32 - Function returns dword
  • abs8 - Function returns byte
  • bcd2bin8 - Function returns byte
  • bin2bcd8 - Function returns byte
  • byte_to_fixed - Function returns sword
  • digits_word - Function returns byte
  • div_fixed - Function returns sdword
  • mod_fixed - Function returns sword
  • mult_fixed - Function returns sdword
  • polar_to_cartesian - Procedure
  • rcos8 - Function returns sword
  • round_fixed - Function returns sbyte
  • rsin8 - Function returns sword
  • sign16 - Function returns sbyte
  • sign32 - Function returns sbyte
  • sign8 - Function returns sbyte
  • sqrt16 - Function returns byte
  • sqrt32 - Function returns word
  • trunc_fixed - Function returns sbyte


max7219_1.jal - JALLIB Library Documentation

max7219_1.jal JALLIB LIBRARY

Title

Library to support a single 8x8 led matrix with MAX7219

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

See the description of max7219.jal.
Dependencies: See max7219.jal

Notes

- This library supports only a single max7219 module.
- The terms 'row' and 'column' are ambiguous: depending on the orientation
of the module! This library calls the LEDs which can be written with a
single write operation a column. Writing a row of a single module requires
8 writes and the cache being active.
See the procedures max7219_display_col() and max7219_display_row().
-----------------------------------------------------------------------------

Routines

  • _max7219_write - Procedure
  • max7219_display_bit - Procedure
  • max7219_display_blink - Procedure
  • max7219_display_byte_bin - Procedure
  • max7219_display_clear - Procedure
  • max7219_display_col - Procedure
  • max7219_display_intensity - Procedure
  • max7219_display_row - Procedure
  • max7219_display_test - Procedure
  • max7219_init - Procedure


max7219_7.jal - JALLIB Library Documentation

max7219_7.jal JALLIB LIBRARY

Title

Library to support an 8-character 7-segment display with MAX7219

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

See the description of max7219_common.jal.
The functionality is similar to the TM1638 library.
This library supports a single MAX7219 module with an 8 character
7-segment display.
This library supports binary, signed and unsigned decimal and unsigned
hexadecimal representations. It does not support display of strings.
Individual digits or segment patterns are addressed from left to right
(offset 0 addresses the leftmost digit). However with the procedures to
display formatted numbers an offset from the right must be specified.
Dependencies: See max7219_common.jal

Notes

- The feature to decode digits to segment patterns (builtin font) is
not used, for the following reasons:
* The builtin font does not support hexadecimal digits (A..F), so
an external font is required anyway, thus the 'no-decode' mode.
* Switching between decode and no-decode mode proved to give
sometimes undesired effects, especially with screen 'blanking'.
-----------------------------------------------------------------------------

Constants and Variables

MAX7219_NUM - const byte = 1
MAX7219_WIDTH - const byte = 8 -- number of 7-segment displays
number of 7-segment displays
rem10 - var byte
quot10 - var dword

Routines

  • _max7219_write - Procedure
  • max7219_display_blink - Procedure
  • max7219_display_byte_bin - Procedure
  • max7219_display_byte_dec - Procedure
  • max7219_display_byte_hex - Procedure
  • max7219_display_clear - Procedure
  • max7219_display_clear_all - Procedure
  • max7219_display_digit - Procedure
  • max7219_display_dword_dec - Procedure
  • max7219_display_dword_hex - Procedure
  • max7219_display_intensity - Procedure
  • max7219_display_pattern - Procedure
  • max7219_display_sbyte_dec - Procedure
  • max7219_display_sdword_dec - Procedure
  • max7219_display_sword_dec - Procedure
  • max7219_display_test - Procedure
  • max7219_display_word_dec - Procedure
  • max7219_display_word_hex - Procedure
  • max7219_init - Procedure


max7219_common.jal - JALLIB Library Documentation

max7219_common.jal JALLIB LIBRARY

Title

Common library for max7219 libraries

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

There are several variants of this library:
- A library for cascaded MAX7219 modules each with an 8x8 LED matrix.
Most procedures of this library require the specification of the module
(sequence number in the chain). Some other procedures apply to all modules
(clear, blink, etc) and need no sequence number.
- A subset of this library for a single MAX7219 module with an 8x8 LED matrix.
Because there is only one module no sequence number is needed in the procedures,
thus this library is somewhat more efficient in terms of code memory and speed.
- A library for a single MAX7219 module with 8 7-segment displays
with a functionality similar to the TM1638 library.
This description applies to all variants, unless otherwise indicated.
.
For multi-module variants you need to specify how many modules are cascaded:
const MAX7219_NUM = <number> -- size of the chain
.
For the 8x8 matrix variants of these libraries:
When you want to control LEDs individually while retaining
the state of the other LEDs a cache must be used. This is a builtin
feature of the libraries, but you have to indicate if you need it.
By default the cache is not active and some functions will not be
available. To activate the cache declare:
const bit MAX7219_DISPLAY_CACHE = TRUE
The cache takes 8 bytes of data memory per MAX7219 module.
.
To initialize the max7219 module(s) call procedure max7219_init().
.
These libraries use either the software SPI library (spi_master_sw, default)
or the hardware SPI library (spi_master_hw).
The advantage of using hardware SPI over software SPI (bit-banging) is
higher efficiency (less CPU cycles and possibly higher speed).
A disadvantage is that it can only be used with PICs with an MSSP module
and that 2 of the 3 leads must be connected to specific pins of the PIC.
.
With software SPI the following needs be declared in the user program before
including the max7219 library:
const bit MAX7219_SPI_HW = FALSE -- (optional, FALSE is default)
alias max7219_din is pin_?? -- pin for data signal (din)
alias max7219_clk is pin_?? -- pin for clock signal (clk)
alias max7219_cs is pin_?? -- pin for chip select signal (cs)
Any pins configurable for digital output can be used for these signals.
.
With hardware SPI the following needs be declared in the user program before
including the max7219[n] library:
const bit MAX7219_SPI_HW = TRUE -- mandatory
alias max7219_cs is pin_?? -- pin for chip select signal (cs)
pin_SDO of the PIC needs be connected to the 'din' pin of the max7219
pin_SCK of the PIC needs be connected to the 'clk' pin of the max7219
Any pin configurable for digital output can be used for max7219_cs
and must be connected to the 'cs' pin of the max7219.
.
Regardless the selected SPI method all 3 used pins must be configured
for output by the user program.
Dependencies: spi_master_hw, spi_master_sw

Notes

-
-----------------------------------------------------------------------------

--------- register address map ------------------

Constants and Variables

MAX7219_NO_OP - const byte = 0b_0000_0000
MAX7219_COL_0 - const byte = 0b_0000_0001
MAX7219_COL_1 - const byte = 0b_0000_0010
MAX7219_COL_2 - const byte = 0b_0000_0011
MAX7219_COL_3 - const byte = 0b_0000_0100
MAX7219_COL_4 - const byte = 0b_0000_0101
MAX7219_COL_5 - const byte = 0b_0000_0110
MAX7219_COL_6 - const byte = 0b_0000_0111
MAX7219_COL_7 - const byte = 0b_0000_1000
MAX7219_DECODE - const byte = 0b_0000_1001
MAX7219_INTENSITY - const byte = 0b_0000_1010
MAX7219_SCANLIMIT - const byte = 0b_0000_1011
MAX7219_SHUTDOWN - const byte = 0b_0000_1100
MAX7219_TEST - const byte = 0b_0000_1111
MAX7219_DISPLAY_PWM1 - const byte = 0b_0000_0000 --
MAX7219_DISPLAY_PWM3 - const byte = 0b_0000_0001 --
MAX7219_DISPLAY_PWM5 - const byte = 0b_0000_0010 --
MAX7219_DISPLAY_PWM7 - const byte = 0b_0000_0011 --
MAX7219_DISPLAY_PWM9 - const byte = 0b_0000_0100 --
MAX7219_DISPLAY_PWM11 - const byte = 0b_0000_0101 -- PWM dutycycle for LEDs
PWM dutycycle for LEDs
MAX7219_DISPLAY_PWM13 - const byte = 0b_0000_0110 --
MAX7219_DISPLAY_PWM15 - const byte = 0b_0000_0111 --
MAX7219_DISPLAY_PWM17 - const byte = 0b_0000_1000 --
MAX7219_DISPLAY_PWM19 - const byte = 0b_0000_1001 --
MAX7219_DISPLAY_PWM21 - const byte = 0b_0000_1010 --
MAX7219_DISPLAY_PWM23 - const byte = 0b_0000_1011 --
MAX7219_DISPLAY_PWM25 - const byte = 0b_0000_1100 --
MAX7219_DISPLAY_PWM27 - const byte = 0b_0000_1101 --
MAX7219_DISPLAY_PWM29 - const byte = 0b_0000_1110 --
MAX7219_DISPLAY_PWM31 - const byte = 0b_0000_1111 --
MAX7219_DP - const byte = 0b_1000_0000 -- segment of decimal point
segment of decimal point
MAX7219_SPI_HW - const bit = FALSE -- declare it, with default setting
declare it, with default setting
MAX7219_DISPLAY_CACHE - const bit = FALSE -- default no caching
default no caching


max7219_display_bit - JALlib Procedures Help

max7219_display_bit JALLIB PROCEDURE

Signature

procedure max7219_display_bit(byte in num, byte in col, byte in row, bit in state) is

Description

Title: Set or reset a single LED
Input: - module number (byte, 0..7)
- column number (byte, 0..7)
- row number (byte, 0..7)
- led state (bit, true or false, on or off)
Notes: - Writes 1 column of one module

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • num - byte in
  • col - byte in
  • row - byte in
  • state - bit in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_blink - JALlib Procedures Help

max7219_display_blink JALLIB PROCEDURE

Signature

procedure max7219_display_blink(byte in times, byte in halfperiod) is

Description

Title: Blink whole module a number of times at a given speed
Input: - number of times the display should blink off and on (byte)
- time in 0.1 seconds of the on and off periods (duty cycle is 50%)
Notes: All 'on' LEDs of all modules will blink simultaneously.

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • times - byte in
  • halfperiod - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_byte_bin - JALlib Procedures Help

max7219_display_byte_bin JALLIB PROCEDURE

Signature

procedure max7219_display_byte_bin(byte in num, byte in col, byte in data) is

Description

Title: Display a column (byte, 8 bits) of one module
Input: - module number (byte, 0..7)
- column number (byte, 0..7)
- with bit pattern to be displayed (byte)

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • num - byte in
  • col - byte in
  • data - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_byte_dec - JALlib Procedures Help

max7219_display_byte_dec JALLIB PROCEDURE

Signature

procedure max7219_display_byte_dec(byte in number,

Description

Title: Display (unsigned) byte as decimal value
Input: - Byte value to be displayed
- Pattern of decimal points (byte with bitmask)
- Offset of the rightmost digit from the rightmost position
- Flag if leading zeroes should be displayed (bit)

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_byte_hex - JALlib Procedures Help

max7219_display_byte_hex JALLIB PROCEDURE

Signature

procedure max7219_display_byte_hex(byte in number, byte in offset) is

Description

Title: Display byte as 2 hexadecimal digits
Input: - Byte value to be displayed
- Offset of the rightmost digit from the rightmost position
Notes: - No decimal points

Include

To use this procedure, include the library:

include max7219_7

Parameters

  • number - byte in
  • offset - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_clear - JALlib Procedures Help

max7219_display_clear JALLIB PROCEDURE

Signature

procedure max7219_display_clear() is

Description

Title: Clear display (all LEDs off)
Input: (none)
Notes: All LEDs of all modules will be cleared
(write 8 times the same column of every module))

Include

To use this procedure, include the library:

include max7219_n

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_clear_all - JALlib Procedures Help

max7219_display_clear_all JALLIB PROCEDURE

Signature

procedure max7219_display_clear_all() is

Description

Title: Clear all display digits (all segments off)
Input: (none)

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_col - JALlib Procedures Help

max7219_display_col JALLIB PROCEDURE

Signature

procedure max7219_display_col(byte in num, byte in col, bit in state) is

Description

Title: Display a column of leds (all leds in a column on or off)
Input: - module number (byte, 0..7)
- column number (byte, 0..7)
- led state (true or false, resp. on or off)

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • num - byte in
  • col - byte in
  • state - bit in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_digit - JALlib Procedures Help

max7219_display_digit JALLIB PROCEDURE

Signature

procedure max7219_display_digit(byte in digit, byte in offset, bit in dp) is

Description

Title: Display a byte with decimal point
Input: - Byte with (hexa)decimal digit to be displayed (0..15)
- Offset of digit from the left (byte, 0..7)
- Flag for decimal point (bit, 0 = no DP, 1 = DP)

Include

To use this procedure, include the library:

include max7219_7

Parameters

  • digit - byte in
  • offset - byte in
  • dp - bit in

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_dword_dec - JALlib Procedures Help

max7219_display_dword_dec JALLIB PROCEDURE

Signature

procedure max7219_display_dword_dec(dword in number,

Description

Title: Display (unsigned) double word as decimal value
Input: - Dword value to be displayed
- Pattern of decimal points (byte with bitmask)
- Offset of the rightmost digit from the rightmost position
- Flag if leading zeroes should be displayed (bit)
Notes: - When the value is too large high order digits are truncated.
- The decimal point(s) pattern is shifted left by 'offset' too.

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_dword_hex - JALlib Procedures Help

max7219_display_dword_hex JALLIB PROCEDURE

Signature

procedure max7219_display_dword_hex(dword in number, byte in offset) is

Description

Title: Display doubleword as 8 hexadecimal digits
Input: - Dword value to be displayed
- Offset of the rightmost digit from the rightmost position
Notes: - No decimal points

Include

To use this procedure, include the library:

include max7219_7

Parameters

  • number - dword in
  • offset - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_intensity - JALlib Procedures Help

max7219_display_intensity JALLIB PROCEDURE

Signature

procedure max7219_display_intensity(byte in intensity) is

Description

Title: Set LED intensity
Input: LED intensity (range 0..15)
Notes: All LEDs of all modules will have the same luminosity

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • intensity - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_pattern - JALlib Procedures Help

max7219_display_pattern JALLIB PROCEDURE

Signature

procedure max7219_display_pattern(byte in pattern, byte in offset) is

Description

Title: Display segment pattern of a digit.
Input: - Segment pattern to be displayed (byte)
- Offset of the digit from the left (byte, 0..7)

Include

To use this procedure, include the library:

include max7219_7

Parameters

  • pattern - byte in
  • offset - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_row - JALlib Procedures Help

max7219_display_row JALLIB PROCEDURE

Signature

procedure max7219_display_row(byte in num, byte in row, bit in state) is

Description

Title: Display a row of leds (all leds in a row on or off) in one module
Input: - module number (byte, 0..7)
- row number (byte, 0..7)
- led state (bit, true or false, resp. on or off)
Notes: - Writes 8 columns of 1 module.

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • num - byte in
  • row - byte in
  • state - bit in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_sbyte_dec - JALlib Procedures Help

max7219_display_sbyte_dec JALLIB PROCEDURE

Signature

procedure max7219_display_sbyte_dec(sbyte in number,

Description

Title: Display signed word as decimal value
Input: - Sword value to be displayed
- Pattern of decimal points (byte with bitmask)
- Offset of the rightmost digit from the rightmost position
- Flag if leading zeroes should be displayed (bit)
Notes: - A minus sign will be in the leftmost display position

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_sdword_dec - JALlib Procedures Help

max7219_display_sdword_dec JALLIB PROCEDURE

Signature

procedure max7219_display_sdword_dec(sdword in number,

Description

Title: Display signed double word as decimal value
Input: - Sdword value to be displayed
- Pattern of decimal points (byte with bitmask)
- Offset of the rightmost digit from the rightmost position
- Flag if leading zeroes should be displayed (bit)
Notes: - A minus sign will be in the leftmost display position.
- When the value is too large high order digits are not displayed.

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_sword_dec - JALlib Procedures Help

max7219_display_sword_dec JALLIB PROCEDURE

Signature

procedure max7219_display_sword_dec(sword in number,

Description

Title: Display signed word as decimal value
Input: - Sword value to be displayed
- Pattern of decimal points (byte with bitmask)
- Offset of the rightmost digit from the rightmost position
- Flag if leading zeroes should be displayed (bit)
Notes: - A minus sign will be in the leftmost display position

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_test - JALlib Procedures Help

max7219_display_test JALLIB PROCEDURE

Signature

procedure max7219_display_test(byte in period) is

Description

Title: Put all MAX7219 modules in test mode for some time.
Input: test period (byte, number of 0.1 seconds)
Notes: All leds will be in maximum intensity during the specified period

Include

To use this procedure, include the library:

include max7219_n

Parameters

  • period - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_display_word_dec - JALlib Procedures Help

max7219_display_word_dec JALLIB PROCEDURE

Signature

procedure max7219_display_word_dec(word in number,

Description

Title: Display (unsigned) word as decimal value
Input: - Word value to be displayed
- Pattern of decimal points (byte with bitmask)
- Offset of the rightmost digit from the rightmost position
- Flag if leading zeroes should be displayed (bit)

Include

To use this procedure, include the library:

include max7219_7

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_display_word_hex - JALlib Procedures Help

max7219_display_word_hex JALLIB PROCEDURE

Signature

procedure max7219_display_word_hex(word in number, byte in offset) is

Description

Title: Display word as 4 hexadecimal digits
Input: - Word value to be displayed
- Offset of the rightmost digit from the rightmost position
Notes: - No decimal points

Include

To use this procedure, include the library:

include max7219_7

Parameters

  • number - word in
  • offset - byte in

Return Value

None

Example

From sample file: 12f1840_max7219_7_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test 7-segment module with MAX7219 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the max7219_c library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 8 7-segment display digits.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz + PLL
pragma target clock    32_000_000    -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL software controlled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz (+PLL -> 32 MHz)
OSCCON_SCS = 0b00                   -- Clock determined by fuses
-- OSCCON_SPLLEN = 0                -- PLL enabled by fuses

enable_digital_io()

include delay

-- --- setup MAX7219 -------------------------------

const bit MAX7219_SPI_HW = TRUE     -- select SPI hardware interface
; const bit MAX7219_SPI_HW = FALSE    -- alternatively select SPI software interface

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs   is pin_A2
pin_A2_direction = OUTPUT

include max7219_7                   -- 7 segment MAX7219 library

delay_100ms(1)                      -- power up delay before init

max7219_init()                      -- initialise the MAX7219

-- --------------------------------------------------

var byte i,j

forever loop

   max7219_display_test(5)                         -- test pattern 1/2 sec
   max7219_display_clear_all()                     -- blank the screen
   max7219_display_intensity(MAX7219_DISPLAY_PWM5) -- low intensity
   delay_100ms(5)                                  -- show blank display

   for 8 using i loop
      for 8 using j loop
         max7219_display_pattern(1 << j, i)        -- 1 segment
         delay_100ms(2)
      end loop
      max7219_display_clear(i)
      delay_100ms(1)
   end loop

   for 8 using i loop
      for 16 using j loop
         max7219_display_digit(j, i, TRUE)         -- digit/char + dp
         delay_100ms(2)
      end loop
      max7219_display_clear_all()
   end loop

   for 8 using i loop
      max7219_display_byte_bin(1 << i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_byte_hex(0xAB, i)
      delay_100ms(5)
   end loop

   for 8 using i loop
      max7219_display_clear_all()
      max7219_display_word_hex(0xCDEF, i)
      delay_100ms(5)
   end loop

   max7219_display_dword_hex(0x12345678, 0)
   delay_100ms(10)

   max7219_display_blink(3,5)

   for 4 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(54321), 0b_0001_1000, i, FALSE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_dword_dec(dword(123), 0b_0000_0100, i, TRUE)
      delay_100ms(10)
   end loop

   for 6 using i loop
      max7219_display_clear_all()
      max7219_display_sdword_dec(sdword(-456), 0b_0000_0100, i, FALSE)
      delay_100ms(10)
   end loop

   max7219_display_clear_all()
   max7219_display_word_dec(word(678), 0b_0000_0100, 0, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sword_dec(sword(-890), 0b_0000_0100, 1, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_byte_dec(byte(255), 0b_0000_0100, 2, FALSE)
   delay_100ms(10)

   max7219_display_clear_all()
   max7219_display_sbyte_dec(sbyte(-127), 0b_0000_0100, 3, FALSE)
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: max7219_7.jal


max7219_font.jal - JALLIB Library Documentation

max7219_font.jal JALLIB LIBRARY

Title

Fonts for MAX7219 seven segment library

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Fonts for MAX7219 7-segment displays.
Only a (hexa)numeric font is supported (chars 0123456789abcdef).
The MAX7219 has a 'reversed' bit representation of the segments
than usual (compared to TM1638/40 and others), see the mapping below:
.
-- 6 --
| |
1 5
| |
-- 0 --
| |
2 4
| |
-- 3 -- .7
Dependencies:
-----------------------------------------------------------------------------

definition for standard (hexa)decimal numbers


max7219_init - JALlib Procedures Help

max7219_init JALLIB PROCEDURE

Signature

procedure max7219_init() is

Description

Title: Initialize all modules with max7219
Input: (none)
Notes: Must be called before any other operation involving the display

Include

To use this procedure, include the library:

include max7219_n

Parameters

None

Return Value

None

Example

From sample file: 12f1840_max7219_n_spi_hw.jal

-- ------------------------------------------------------
-- Title: Test a chain of 8x8 LED matrices with MAX7219 chips
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the MAX7219_N library.
-- It can use the SPI hardware or the SPI software library,
-- selected by a constant (see max7219_common.jal)
-- Most available procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a chain of 3 ready-built PCBs with 8x8 led matrix display.
--
-- Sources:
--
-- Notes: See also samples for a single MAX7219 module
--
-- ------------------------------------------------------
--
-- chip setup
include 12f1840

-- This program uses the Internal oscillator at 8 MHz with PLL enabled
pragma target clock    32_000_000   -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target WDT      DISABLED     -- watchdog
pragma target PWRTE    ENABLED      -- powerup delay
pragma target MCLR     EXTERNAL     -- reset externally
pragma target BROWNOUT DISABLED     -- no brownout
pragma target IESO     DISABLED     -- no osc switchover
pragma target PLLEN    ENABLED      -- PLL enabled
pragma target LVP      ENABLED      -- allow LVP

-- setup internal oscillator

OSCCON_IRCF = 0b1110                -- 8 MHz
OSCCON_SCS = 0b00                   -- Clock determined by fuses

enable_digital_io()

-- --- setup MAX7219 -------------------------------------

const byte MAX7219_NUM   = 3        -- 3 chained MAX7219 modules
const bit MAX7219_SPI_HW = TRUE     -- use hardware SPI

if (MAX7219_SPI_HW == TRUE) then
   if (defined(APFCON_SDOSEL)) then
      apfcon_sdosel = 0             -- configure SDO on pin RA0
      alias pin_SDO_direction is pin_SDO_RA0_direction
   end if
   pin_SDO_direction = OUTPUT       -- SDO = pin_A0
   pin_SCK_direction = OUTPUT       -- CLK = pin_A1
else
   alias max7219_din is pin_A0
   alias max7219_clk is pin_A1
   pin_A0_direction  =  OUTPUT
   pin_A1_direction  =  OUTPUT
end if

alias max7219_cs  is pin_A2
pin_A2_direction  = OUTPUT

const bit MAX7219_DISPLAY_CACHE = TRUE   -- use cache

include max7219_n                    -- multimodule library
delay_100ms(1)                       -- power up delay before init
max7219_init()                       -- initalize the MAX7219s

-- ------------------------------------------------------

var byte i,j

forever loop

   max7219_display_clear()
   max7219_display_test(5)
   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   for MAX7219_NUM using i loop
      for 8 using j loop
         max7219_display_col(i, j, TRUE)
         delay_100ms(2)
         max7219_display_col(i, j, FALSE)
      end loop
   end loop

   for 8 using i loop
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, TRUE)
      end loop
      delay_100ms(2)
      for MAX7219_NUM using j loop
         max7219_display_row(j, i, FALSE)
      end loop
   end loop

   for 8 using i loop
      max7219_display_bit(0, i, i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(1, i, 7 - i, TRUE)
      delay_100ms(1)
   end loop
   for 8 using i loop
      max7219_display_bit(2, i, i, TRUE)
      delay_100ms(1)
   end loop

   max7219_display_blink(3,3)             -- blink

   for 16 using i loop                    -- intensity range
      max7219_display_intensity(i)
      delay_100ms(2)
   end loop

   max7219_display_intensity(MAX7219_DISPLAY_PWM3)

   const byte v[] = {24,60,126,255}
   const byte h[] = {24,36,66,129}
   for 4 using i loop                     -- big bang
      for 4 using j loop
         if j < i then
            max7219_display_byte_bin(1, 3 - j, h[i])
            max7219_display_byte_bin(1, 4 + j, h[i])
         elsif j == i then
            max7219_display_byte_bin(1, 3 - j, v[i])
            max7219_display_byte_bin(1, 4 + j, v[i])
         else
            max7219_display_byte_bin(1, 3 - j, 0)
            max7219_display_byte_bin(1, 4 + j, 0)
         end if
      end loop
      delay_100ms(3)
   end loop
   delay_100ms(5)

   const byte s[] = {60,66,165,141,141,165,66,60}
   for 8 using i loop
      max7219_display_byte_bin(1, i, s[i])
   end loop
   for 3 using i loop
      delay_100ms(5)
      max7219_display_bit(1, 5, 5, FALSE)
      delay_100ms(2)
      max7219_display_bit(1, 5, 5, TRUE)
   end loop
   delay_100ms(5)

end loop

Generated by JALlib CHM Help System | Source: max7219_n.jal


max7219_n.jal - JALLIB Library Documentation

max7219_n.jal JALLIB LIBRARY

Title

Library to support cascaded 8x8 led matrices with MAX7219s

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

See the description of max7219.jal.
Dependencies: See max7219.jal

Notes

- This library is designed for max7219 modules controlling an 8x8 LED matrix,
the features of the MAX7219 chips for 7-segment displays are disabled.
- The terms 'row' and 'column' are ambiguous: depending on the orientation
of the module! This library calls the LEDs which can be written with a
single write operation a column. Writing a row of a single module requires
8 writes and the cache being active.
See the procedures max7219_display_col() and max7219_display_row().
-----------------------------------------------------------------------------

Constants and Variables

MAX7219_NUM - const byte = 2 -- default
default

Routines

  • _max7219_write - Procedure
  • _max7219_write_all - Procedure
  • max7219_display_bit - Procedure
  • max7219_display_blink - Procedure
  • max7219_display_byte_bin - Procedure
  • max7219_display_clear - Procedure
  • max7219_display_col - Procedure
  • max7219_display_intensity - Procedure
  • max7219_display_row - Procedure
  • max7219_display_test - Procedure
  • max7219_init - Procedure


mcp23s08.jal - JALLIB Library Documentation

mcp23s08.jal JALLIB LIBRARY

Title

Library functions for the MCP23S08.

Author

Rob Jansen, Copyright (c) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library functions for the MCP23S08. The port and individual
port bits are all accessed using pseudo variables. In this way
accessing the pins is the same as accessing PIC IO pins.
The provided pin functions are (x = 0..7):
mcp23s08_pinx_direction using value INPUT/OUTPUT
mcp23s08_pinx_polarty using value ENABLED/DISABLED
mcp23s08_pinx using value HIGH/LOW
mcp23s08_latchx using value HIGH/LOW
mcp23s08_pull_upx using value ENABLED/DISABLED
Port pseudo variables, activating all pins at once:
mcp23s08_port_direction Bits 0 = output, 1 = input
mcp23s08_port_polarity Bits 0 = normal, 1 = inverted
mcp23s08_port Bits 0 = LOW, 1 = HIGH
mcp23s08_latch Bits 0 = LOW, 1 = HIGH
mcp23s08_pull_up Bits 0 = DISABLED, 1 = ENABLED
All other functions are provided via procedures and functions as
described in the Public API section.
The default SPI address of 0x40 can be overruled by defining:
const byte MCP23S08_SPI_ADDRESS = <address>
Note that the use of the SPI address can be disabled (default).
The user must initialize the SPI pins and interface and needs to
define the following pin for this library:
alias mcp23s08_csn is <PIC pin>
This pin must be set to output by the user.

Sources

Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
Datasheet DS20001919F.

---------------------- PUBLIC CONSTANTS DEFS --------------------------------

Default SPI address if not defined by the user. Address is defined as:
0 1 0 0 0 A1 A0 R/W (W = 0 is write which must be the default value).

Constants and Variables

MCP23S08_SPI_ADDRESS - const byte = 0b0100_0000 -- A0 and A1 both to GND.
A0 and A1 both to GND.
data - var byte
selector - var byte = 0b0000_0001
data - var byte
selector - var byte = 0b0000_0001

Routines

  • _mcp23s08_get_register_bit - Function returns bit
  • _mcp23s08_read_data - Function returns byte
  • _mcp23s08_update_register_bit - Procedure
  • _mcp23s08_write_data - Procedure
  • mcp23s08_disable_hardware_address - Procedure
  • mcp23s08_enable_hardware_address - Procedure
  • mcp23s08_get_interrupt_capture - Function returns byte
  • mcp23s08_get_interrupt_flags - Function returns byte
  • mcp23s08_latch'get - Function returns byte
  • mcp23s08_latch'put - Procedure
  • mcp23s08_latch0'get - Function returns bit
  • mcp23s08_latch0'put - Procedure
  • mcp23s08_latch1'get - Function returns bit
  • mcp23s08_latch1'put - Procedure
  • mcp23s08_latch2'get - Function returns bit
  • mcp23s08_latch2'put - Procedure
  • mcp23s08_latch3'get - Function returns bit
  • mcp23s08_latch3'put - Procedure
  • mcp23s08_latch4'get - Function returns bit
  • mcp23s08_latch4'put - Procedure
  • mcp23s08_latch5'get - Function returns bit
  • mcp23s08_latch5'put - Procedure
  • mcp23s08_latch6'get - Function returns bit
  • mcp23s08_latch6'put - Procedure
  • mcp23s08_latch7'get - Function returns bit
  • mcp23s08_latch7'put - Procedure
  • mcp23s08_pin0'get - Function returns bit
  • mcp23s08_pin0'put - Procedure
  • mcp23s08_pin0_direction'get - Function returns bit
  • mcp23s08_pin0_direction'put - Procedure
  • mcp23s08_pin0_polarity'get - Function returns bit
  • mcp23s08_pin0_polarity'put - Procedure
  • mcp23s08_pin1'get - Function returns bit
  • mcp23s08_pin1'put - Procedure
  • mcp23s08_pin1_direction'get - Function returns bit
  • mcp23s08_pin1_direction'put - Procedure
  • mcp23s08_pin1_polarity'get - Function returns bit
  • mcp23s08_pin1_polarity'put - Procedure
  • mcp23s08_pin2'get - Function returns bit
  • mcp23s08_pin2'put - Procedure
  • mcp23s08_pin2_direction'get - Function returns bit
  • mcp23s08_pin2_direction'put - Procedure
  • mcp23s08_pin2_polarity'get - Function returns bit
  • mcp23s08_pin2_polarity'put - Procedure
  • mcp23s08_pin3'get - Function returns bit
  • mcp23s08_pin3'put - Procedure
  • mcp23s08_pin3_direction'get - Function returns bit
  • mcp23s08_pin3_direction'put - Procedure
  • mcp23s08_pin3_polarity'get - Function returns bit
  • mcp23s08_pin3_polarity'put - Procedure
  • mcp23s08_pin4'get - Function returns bit
  • mcp23s08_pin4'put - Procedure
  • mcp23s08_pin4_direction'get - Function returns bit
  • mcp23s08_pin4_direction'put - Procedure
  • mcp23s08_pin4_polarity'get - Function returns bit
  • mcp23s08_pin4_polarity'put - Procedure
  • mcp23s08_pin5'get - Function returns bit
  • mcp23s08_pin5'put - Procedure
  • mcp23s08_pin5_direction'get - Function returns bit
  • mcp23s08_pin5_direction'put - Procedure
  • mcp23s08_pin5_polarity'get - Function returns bit
  • mcp23s08_pin5_polarity'put - Procedure
  • mcp23s08_pin6'get - Function returns bit
  • mcp23s08_pin6'put - Procedure
  • mcp23s08_pin6_direction'get - Function returns bit
  • mcp23s08_pin6_direction'put - Procedure
  • mcp23s08_pin6_polarity'get - Function returns bit
  • mcp23s08_pin6_polarity'put - Procedure
  • mcp23s08_pin7'get - Function returns bit
  • mcp23s08_pin7'put - Procedure
  • mcp23s08_pin7_direction'get - Function returns bit
  • mcp23s08_pin7_direction'put - Procedure
  • mcp23s08_pin7_polarity'get - Function returns bit
  • mcp23s08_pin7_polarity'put - Procedure
  • mcp23s08_port'get - Function returns byte
  • mcp23s08_port'put - Procedure
  • mcp23s08_port_direction'get - Function returns byte
  • mcp23s08_port_direction'put - Procedure
  • mcp23s08_port_polarity'get - Function returns byte
  • mcp23s08_port_polarity'put - Procedure
  • mcp23s08_pull_up'get - Function returns byte
  • mcp23s08_pull_up'put - Procedure
  • mcp23s08_pull_up0'get - Function returns bit
  • mcp23s08_pull_up0'put - Procedure
  • mcp23s08_pull_up1'get - Function returns bit
  • mcp23s08_pull_up1'put - Procedure
  • mcp23s08_pull_up2'get - Function returns bit
  • mcp23s08_pull_up2'put - Procedure
  • mcp23s08_pull_up3'get - Function returns bit
  • mcp23s08_pull_up3'put - Procedure
  • mcp23s08_pull_up4'get - Function returns bit
  • mcp23s08_pull_up4'put - Procedure
  • mcp23s08_pull_up5'get - Function returns bit
  • mcp23s08_pull_up5'put - Procedure
  • mcp23s08_pull_up6'get - Function returns bit
  • mcp23s08_pull_up6'put - Procedure
  • mcp23s08_pull_up7'get - Function returns bit
  • mcp23s08_pull_up7'put - Procedure
  • mcp23s08_set_interrupt_active_high - Procedure
  • mcp23s08_set_interrupt_active_low - Procedure
  • mcp23s08_set_interrupt_compare_value - Procedure
  • mcp23s08_set_interrupt_control - Procedure
  • mcp23s08_set_interrupt_on_change - Procedure
  • mcp23s08_set_interrupt_output_driving - Procedure
  • mcp23s08_set_interrupt_output_open_drain - Procedure


mcp23s08_disable_hardware_address - JALlib Procedures Help

mcp23s08_disable_hardware_address JALLIB PROCEDURE

Signature

procedure mcp23s08_disable_hardware_address() is

Description

Disable the use of the SPI hardware address.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

None

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_enable_hardware_address - JALlib Procedures Help

mcp23s08_enable_hardware_address JALLIB PROCEDURE

Signature

procedure mcp23s08_enable_hardware_address() is

Description

Enable the use of the SPI hardware address.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

None

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_get_interrupt_flags - JALlib Procedures Help

mcp23s08_get_interrupt_flags JALLIB FUNCTION

Signature

function mcp23s08_get_interrupt_flags() return byte is

Description

Return the interrupt flags. See datasheet for details.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_set_interrupt_active_low - JALlib Procedures Help

mcp23s08_set_interrupt_active_low JALLIB PROCEDURE

Signature

procedure mcp23s08_set_interrupt_active_low() is

Description

Set the interrupt polarity to active LOW.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

None

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_set_interrupt_compare_value - JALlib Procedures Help

mcp23s08_set_interrupt_compare_value JALLIB PROCEDURE

Signature

procedure mcp23s08_set_interrupt_compare_value(byte in value) is

Description

Set interrupt compare value. See datasheet for details.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_set_interrupt_control - JALlib Procedures Help

mcp23s08_set_interrupt_control JALLIB PROCEDURE

Signature

procedure mcp23s08_set_interrupt_control(byte in value) is

Description

Set the interrupt control value. See datasheet for details.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_set_interrupt_on_change - JALlib Procedures Help

mcp23s08_set_interrupt_on_change JALLIB PROCEDURE

Signature

procedure mcp23s08_set_interrupt_on_change(byte in value) is

Description

Set interrupt on change register. Bit set is ENABLE, bit clear is DISABLE.
See datasheet for details.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp23s08_set_interrupt_output_driving - JALlib Procedures Help

mcp23s08_set_interrupt_output_driving JALLIB PROCEDURE

Signature

procedure mcp23s08_set_interrupt_output_driving() is

Description

Set the interrupt output to driving.

Include

To use this procedure, include the library:

include mcp23s08

Parameters

None

Return Value

None

Example

From sample file: 16f1825_mcp23s08.jal

-- Title: Sample and test program for the MCP23S08 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23S08 8-Bit I/O Expander.
--              This device is controlled via an SPI interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23S08 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the the SPI hardware address, including disabling it
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23S08 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the SPI pins and initiaize the pin direction.
pin_C0_direction = output     -- SCK pin 10 to pin 1 of IC (SCK).
pin_C1_direction = input      -- SDI pin  9 to pin 3 of IC (SO)
pin_C2_direction = output     -- SDO pin  8 to pin 2 of IC (SI).
alias mcp23s08_csn is pin_C3  -- Needed for library to control the CS pin.
mcp23s08_csn = high
pin_C3_direction = output     -- CS pin 7 to pin 7 of IC (CS).

-- Now include the used SPI interface.
include spi_host_hw
-- Set SPI mode 00 that is data is clocked on the rising edge.
-- When target_clock > 40 MHz use SPI_RATE_FOSC_16.
spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
-- Define the interface alias for the MCP23S08.
alias mcp23s08_spi_host is spi_host_hw
-- Now include the library.
include mcp23s08

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23s08_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23s08_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23s08_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23s08_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23s08_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23s08_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23s08_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23s08_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23s08_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the SPI hardware address.
const TEST_4 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23S08.\r\n")

forever  loop

   -- Initialize port.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port_polarity = ALL_DISABLED
   mcp23s08_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23s08_port = 0x00
   wait()
   mcp23s08_port = 0xFF
   wait()
   mcp23s08_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23s08_latch = 0x00
   wait()
   mcp23s08_latch = 0xFF
   wait()
   mcp23s08_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23s08_pin0 = HIGH
   wait()
   mcp23s08_pin1 = HIGH
   wait()
   mcp23s08_pin2 = HIGH
   wait()
   mcp23s08_pin3 = HIGH
   wait()
   mcp23s08_pin4 = HIGH
   wait()
   mcp23s08_pin5 = HIGH
   wait()
   mcp23s08_pin6 = HIGH
   wait()
   mcp23s08_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23s08_latch0 = LOW
   wait()
   mcp23s08_latch1 = LOW
   wait()
   mcp23s08_latch2 = LOW
   wait()
   mcp23s08_latch3 = LOW
   wait()
   mcp23s08_latch4 = LOW
   wait()
   mcp23s08_latch5 = LOW
   wait()
   mcp23s08_latch6 = LOW
   wait()
   mcp23s08_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23s08_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pin2_direction = INPUT
   mcp23s08_pin3_direction = INPUT
   mcp23s08_pin4_direction = INPUT
   mcp23s08_pin5_direction = INPUT
   mcp23s08_pin6_direction = INPUT
   mcp23s08_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23s08_pull_up0 = ENABLED
   mcp23s08_pull_up1 = ENABLED
   mcp23s08_pull_up2 = ENABLED
   mcp23s08_pull_up3 = ENABLED
   mcp23s08_pull_up4 = ENABLED
   mcp23s08_pull_up5 = ENABLED
   mcp23s08_pull_up6 = ENABLED
   mcp23s08_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23s08_pull_up = ALL_DISABLED
   mcp23s08_pin0_polarity = ENABLED
   mcp23s08_pin1_polarity = ENABLED
   mcp23s08_pin2_polarity = ENABLED
   mcp23s08_pin3_polarity = ENABLED
   mcp23s08_pin4_polarity = ENABLED
   mcp23s08_pin5_polarity = ENABLED
   mcp23s08_pin6_polarity = ENABLED
   mcp23s08_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23s08_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23s08_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
  -- SPI hardware address tests. Initially (after power up) the hardware address is ignored.
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_disable_hardware_address() -- This is the default at power up.
   print_string(serial_data, "At power up the SPI hardware address is disabled.\r\n")
   print_string(serial_data, "Change one hardware address line on the chip and press any key.\r\n")
   print_string(serial_data, "Pin 0 but be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin0 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Restore the hardware address line on the chip.\r\n")
   print_string(serial_data, "Now the SPI hardware address will enabled.\r\n")
   print_string(serial_data, "Press an key and pin 1 must be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_enable_hardware_address() -- This only works if the hardware address is set to the SPI address.
   mcp23s08_pin1 = HIGH
   print_crlf(serial_data)

   print_string(serial_data, "Change the hardware address line of the chip and press key pressed.\r\n")
   print_string(serial_data, "Pin 2 must not be HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_pin2 = HIGH -- This should not work since the hardware address differs from the SPI address.
   print_crlf(serial_data)

   print_string(serial_data, "Restore hardware address and press any key.\r\n")
   print_string(serial_data, "Pin 3 will go HIGH.\r\n")
   while !key_is_pressed() loop end loop
   mcp23s08_disable_hardware_address() -- Can only be disabled when address is correct again!
   mcp23s08_pin3 = HIGH
   print_crlf(serial_data)
end if

if defined(TEST_4) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port_direction = ALL_OUTPUT
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin0_direction = INPUT
   mcp23s08_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23s08_set_interrupt_output_driving() -- Not open drain.
   mcp23s08_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23s08_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23s08_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23s08_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23s08_pin7 = HIGH
   else
      mcp23s08_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   mcp23s08_pin1_direction = INPUT
   mcp23s08_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin6 = HIGH
   else
      mcp23s08_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23s08_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23s08_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23s08_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23s08_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23s08_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23s08_pin5 = HIGH
   else
      mcp23s08_pin4 = HIGH
   end if
   mcp23s08_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23s08.jal


mcp3424.jal - JALLIB Library Documentation

mcp3424.jal JALLIB LIBRARY

Title

mcp342, 18-bit, multi-channel delta-sigma AD converter with I2C output

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2010, Adapted-by: William Welch

Compiler

=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library works with the MCP3424 AD converter from Microchip with up to 18 bits accuracy
Datasheet: DS22088B
Declare this in main program:

if you want to use more than one MCP3424, use the address pins:
const byte mcp3424_1_addr = 0b1101_0000 -- both ADR0 and ADR1 tied to Vss
const byte mcp3424_2_addr = 0b1101_1000 -- ADR0 tied to Vdd, ADR1 tied to Vss
i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true ; i2c levels (not SMB)
include i2c_hardware
i2c_initialize()

Routines

  • mcp3424_get_16 - Function returns sword
  • mcp3424_get_16_status - Function returns sword
  • mcp3424_get_18 - Function returns sdword
  • mcp3424_get_18_status - Function returns sdword
  • mcp3424_microvolt - Function returns sdword
  • mcp3424_millivolt - Function returns sword
  • mcp3424_set18bits - Function returns bit
  • mcp3424_set_channel - Function returns bit
  • mcp3424_set_gain - Function returns bit


mcp4131_init - JALlib Procedures Help

mcp4131_init JALLIB PROCEDURE

Signature

procedure mcp4131_init() is

Description

Init.

Include

To use this procedure, include the library:

include digital_potentiometer_mcp4131

Parameters

None

Return Value

None

Example

From sample file: 18f4620_digital_potentiometer_mcp4131.jal

-- Title: Digital potentiometer mcp4131 sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample controls digital potentiometer mcp4131
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target OSC INTOSC_NOCLKOUT -- internal oscillator
                                  -- and using PLL
pragma target CLOCK 32_000_000    -- oscillator frequency
pragma target WDT      CONTROL      -- watchdog
pragma target XINST    DISABLED     -- not supported by JalV2
pragma target DEBUG    DISABLED     -- no debugging
pragma target IESO     DISABLED     -- no in/ext oscillator switchover
pragma target LVP      ENABLED      -- allow Low Voltage Programming
pragma target MCLR     EXTERNAL     -- reset externally
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup digital potentiometer mcp4131
alias mcp4131_ss is pin_ss
alias mcp4131_ss_direction is pin_ss_direction
--
include digital_potentiometer_mcp4131
mcp4131_init()
--
alias pot_wiper is mcp4131_wiper
alias pot_increment is mcp4131_increment
alias pot_decrement is mcp4131_decrement

pot_wiper = 0 -- set wiper to zero
var byte step = 0

forever loop
   pot_wiper = step
   step = step + 1

;   for 255 loop
;      pot_increment()
;   end loop
;   for 255 loop
;      pot_decrement()
;   end loop
end loop

Generated by JALlib CHM Help System | Source: digital_potentiometer_mcp4131.jal


mcp4922_dac_a - JALlib Procedures Help

mcp4922_dac_a JALLIB PROCEDURE

Signature

procedure mcp4922_dac_a(word in A) is

Description

Function to write to the DAC A and latch

Include

To use this procedure, include the library:

include dac_mcp4922

Parameters

  • A - word in

Return Value

None

Example

From sample file: 18f27j53_mcp4922.jal

--------------------------------------------------------------------------------
-- Title: MCP4922_example.jal
-- Author: Peter Lankreijer
-- Adapted-by: Sebastien Lelong, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This program is to show the usage of the MCP4922 library.
--
-- This file has been generated by hand (manually maintained)
--

include 18f27j53

pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

include delay

-- setup SPI
alias spi_master_sw_sdi                  is pin_B2
alias spi_master_sw_sdi_direction        is pin_B2_direction
alias spi_master_sw_sdo                  is pin_A2
alias spi_master_sw_sdo_direction        is pin_A2_direction
alias spi_master_sw_sck                  is pin_A3
alias spi_master_sw_sck_direction        is pin_A3_direction

include spi_master_sw

spi_master_sw_sdi_direction = input      -- spi input
spi_master_sw_sdo_direction = output     -- spi output
spi_master_sw_sck_direction = output     -- spi clock

spi_master_sw_init(SPI_MODE_11)
alias spi_master is spi_master_sw
alias spi_master_exchange is spi_master_sw_exchange

-- setup of the DAC
alias mcp4922_cs                         is pin_A1
alias mcp4922_cs_direction               is pin_A1_direction
alias mcp4922_ldac                       is pin_A7
alias mcp4922_ldac_direction             is pin_A7_direction

var bit buffer = 1                       -- buffered
var bit gain = 0                         -- 2 * Vref * D/4096

include dac_mcp4922

mcp4922_init(buffer, gain)

-- main program

var word dac_value_a = 0              -- value between 0 and 4096
var word dac_value_b = 4000

forever loop
   for 20 loop
       dac_value_a = dac_value_a + 200
       dac_value_b = dac_value_b - 200

       mcp4922_dac_ab(dac_value_a, dac_value_b)

       delay_100ms(5)
   end loop

   for 20 loop
       dac_value_a = dac_value_a - 200
       dac_value_b = dac_value_b + 200

       mcp4922_dac_a(dac_value_a)
       mcp4922_dac_a(dac_value_b)

       delay_100ms(5)
   end loop

end loop

Generated by JALlib CHM Help System | Source: dac_mcp4922.jal


mcp4922_dac_ab - JALlib Procedures Help

mcp4922_dac_ab JALLIB PROCEDURE

Signature

procedure mcp4922_dac_ab(word in A, word in B) is

Description

Function to write to the DAC and update both registers at the same time

Include

To use this procedure, include the library:

include dac_mcp4922

Parameters

  • A - word in
  • B - word in

Return Value

None

Example

From sample file: 18f27j53_mcp4922.jal

--------------------------------------------------------------------------------
-- Title: MCP4922_example.jal
-- Author: Peter Lankreijer
-- Adapted-by: Sebastien Lelong, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This program is to show the usage of the MCP4922 library.
--
-- This file has been generated by hand (manually maintained)
--

include 18f27j53

pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

include delay

-- setup SPI
alias spi_master_sw_sdi                  is pin_B2
alias spi_master_sw_sdi_direction        is pin_B2_direction
alias spi_master_sw_sdo                  is pin_A2
alias spi_master_sw_sdo_direction        is pin_A2_direction
alias spi_master_sw_sck                  is pin_A3
alias spi_master_sw_sck_direction        is pin_A3_direction

include spi_master_sw

spi_master_sw_sdi_direction = input      -- spi input
spi_master_sw_sdo_direction = output     -- spi output
spi_master_sw_sck_direction = output     -- spi clock

spi_master_sw_init(SPI_MODE_11)
alias spi_master is spi_master_sw
alias spi_master_exchange is spi_master_sw_exchange

-- setup of the DAC
alias mcp4922_cs                         is pin_A1
alias mcp4922_cs_direction               is pin_A1_direction
alias mcp4922_ldac                       is pin_A7
alias mcp4922_ldac_direction             is pin_A7_direction

var bit buffer = 1                       -- buffered
var bit gain = 0                         -- 2 * Vref * D/4096

include dac_mcp4922

mcp4922_init(buffer, gain)

-- main program

var word dac_value_a = 0              -- value between 0 and 4096
var word dac_value_b = 4000

forever loop
   for 20 loop
       dac_value_a = dac_value_a + 200
       dac_value_b = dac_value_b - 200

       mcp4922_dac_ab(dac_value_a, dac_value_b)

       delay_100ms(5)
   end loop

   for 20 loop
       dac_value_a = dac_value_a - 200
       dac_value_b = dac_value_b + 200

       mcp4922_dac_a(dac_value_a)
       mcp4922_dac_a(dac_value_b)

       delay_100ms(5)
   end loop

end loop

Generated by JALlib CHM Help System | Source: dac_mcp4922.jal


mcp4922_init - JALlib Procedures Help

mcp4922_init JALLIB PROCEDURE

Signature

procedure mcp4922_init(bit in buffer, bit in gain) is

Description

Initialise the MCP4922

Include

To use this procedure, include the library:

include dac_mcp4922

Parameters

  • buffer - bit in
  • gain - bit in

Return Value

None

Example

From sample file: 18f27j53_mcp4922.jal

--------------------------------------------------------------------------------
-- Title: MCP4922_example.jal
-- Author: Peter Lankreijer
-- Adapted-by: Sebastien Lelong, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This program is to show the usage of the MCP4922 library.
--
-- This file has been generated by hand (manually maintained)
--

include 18f27j53

pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

include delay

-- setup SPI
alias spi_master_sw_sdi                  is pin_B2
alias spi_master_sw_sdi_direction        is pin_B2_direction
alias spi_master_sw_sdo                  is pin_A2
alias spi_master_sw_sdo_direction        is pin_A2_direction
alias spi_master_sw_sck                  is pin_A3
alias spi_master_sw_sck_direction        is pin_A3_direction

include spi_master_sw

spi_master_sw_sdi_direction = input      -- spi input
spi_master_sw_sdo_direction = output     -- spi output
spi_master_sw_sck_direction = output     -- spi clock

spi_master_sw_init(SPI_MODE_11)
alias spi_master is spi_master_sw
alias spi_master_exchange is spi_master_sw_exchange

-- setup of the DAC
alias mcp4922_cs                         is pin_A1
alias mcp4922_cs_direction               is pin_A1_direction
alias mcp4922_ldac                       is pin_A7
alias mcp4922_ldac_direction             is pin_A7_direction

var bit buffer = 1                       -- buffered
var bit gain = 0                         -- 2 * Vref * D/4096

include dac_mcp4922

mcp4922_init(buffer, gain)

-- main program

var word dac_value_a = 0              -- value between 0 and 4096
var word dac_value_b = 4000

forever loop
   for 20 loop
       dac_value_a = dac_value_a + 200
       dac_value_b = dac_value_b - 200

       mcp4922_dac_ab(dac_value_a, dac_value_b)

       delay_100ms(5)
   end loop

   for 20 loop
       dac_value_a = dac_value_a - 200
       dac_value_b = dac_value_b + 200

       mcp4922_dac_a(dac_value_a)
       mcp4922_dac_a(dac_value_b)

       delay_100ms(5)
   end loop

end loop

Generated by JALlib CHM Help System | Source: dac_mcp4922.jal


mcp9800.jal - JALLIB Library Documentation

mcp9800.jal JALLIB LIBRARY

Title

mcp9800

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2010, Adapted-by: William Welch

Compiler

=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library works with the MCP9800 temperature sensor from microchip
The MCP9800 can do 9 to 12 bit temperature measurement resolution
in the 12bit mode, the LSb represents 1/16C
only 12 bit routines are given here
Uses: i2c_hardware or i2c_software I2C library

Datasheet: DS21909B

MCP9800 I2C sensor
part used is MCP9800/02A0 with internal adress set to 0b1001_0000, last bit is read /write
register pointer map:
0b0000_0000 temperature register (16 bits)
0b0000_0001 configuration register ( 8 bits)
0b0000_0010 temperature Hysteresis register (8 bits)
0b0000_0011 temperature Limit-set register (8 bits)

Constants and Variables

mcp9800_addr - const byte = 0b1001_0000 -- read/write is done by i2c library
read/write is done by i2c library

Routines

  • mcp9800_12bit - Function returns sword
  • mcp9800_celsius - Function returns sbyte
  • mcp9800_centicelsius - Function returns sword
  • mcp9800_set_12_bits_temperature - Function returns bit


mcp23008.jal - JALLIB Library Documentation

mcp23008.jal JALLIB LIBRARY

Title

Library functions for the MSP23008.

Author

Rob Jansen, Copyright (c) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library functions for the MSP23008. The port and individual
port bits are all accessed using pseudo variables. In this way
accessing the pins is the same as accessing PIC IO pins.
The provided pin functions are (x = 0..7):
mcp23008_pinx_direction using value INPUT/OUTPUT
mcp23008_pinx_polarty using value ENABLED/DISABLED
mcp23008_pinx using value HIGH/LOW
mcp23008_latchx using value HIGH/LOW
mcp23008_pull_upx using value ENABLED/DISABLED
Port pseudo variables, activating all pins at once:
mcp23008_port_direction Bits 0 = output, 1 = input
mcp23008_port_polarity Bits 0 = normal, 1 = inverted
mcp23008_port Bits 0 = LOW, 1 = HIGH
mcp23008_latch Bits 0 = LOW, 1 = HIGH
mcp23008_pull_up Bits 0 = DISABLED, 1 = ENABLED
All other functions are provided via procedures and functions as
described in the Public API section.
The default IIC address of 0x40 can be overruled by defining:
const byte MCP23008_IIC_ADDRESS = <address>
This pin must be set to output by the user.

Sources

Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
Datasheet DS20001919F.

---------------------- PUBLIC CONSTANTS DEFS --------------------------------

Default IIC address if not defined by the user. Address is defined as:
0 1 0 0 A2 A1 A0 R/W (W = 0 is write which must be the default value).

Constants and Variables

MCP23008_IIC_ADDRESS - const byte = 0b0100_0000 -- A0..A2 to GND.
A0..A2 to GND.
data - var byte
selector - var byte = 0b0000_0001
data - var byte
selector - var byte = 0b0000_0001

Routines

  • _mcp23008_get_register_bit - Function returns bit
  • _mcp23008_read_data - Function returns byte
  • _mcp23008_update_register_bit - Procedure
  • _mcp23008_write_data - Procedure
  • mcp23008_disable_slew_rate - Procedure
  • mcp23008_get_interrupt_capture - Function returns byte
  • mcp23008_get_interrupt_flags - Function returns byte
  • mcp23008_latch'get - Function returns byte
  • mcp23008_latch'put - Procedure
  • mcp23008_latch0'get - Function returns bit
  • mcp23008_latch0'put - Procedure
  • mcp23008_latch1'get - Function returns bit
  • mcp23008_latch1'put - Procedure
  • mcp23008_latch2'get - Function returns bit
  • mcp23008_latch2'put - Procedure
  • mcp23008_latch3'get - Function returns bit
  • mcp23008_latch3'put - Procedure
  • mcp23008_latch4'get - Function returns bit
  • mcp23008_latch4'put - Procedure
  • mcp23008_latch5'get - Function returns bit
  • mcp23008_latch5'put - Procedure
  • mcp23008_latch6'get - Function returns bit
  • mcp23008_latch6'put - Procedure
  • mcp23008_latch7'get - Function returns bit
  • mcp23008_latch7'put - Procedure
  • mcp23008_pin0'get - Function returns bit
  • mcp23008_pin0'put - Procedure
  • mcp23008_pin0_direction'get - Function returns bit
  • mcp23008_pin0_direction'put - Procedure
  • mcp23008_pin0_polarity'get - Function returns bit
  • mcp23008_pin0_polarity'put - Procedure
  • mcp23008_pin1'get - Function returns bit
  • mcp23008_pin1'put - Procedure
  • mcp23008_pin1_direction'get - Function returns bit
  • mcp23008_pin1_direction'put - Procedure
  • mcp23008_pin1_polarity'get - Function returns bit
  • mcp23008_pin1_polarity'put - Procedure
  • mcp23008_pin2'get - Function returns bit
  • mcp23008_pin2'put - Procedure
  • mcp23008_pin2_direction'get - Function returns bit
  • mcp23008_pin2_direction'put - Procedure
  • mcp23008_pin2_polarity'get - Function returns bit
  • mcp23008_pin2_polarity'put - Procedure
  • mcp23008_pin3'get - Function returns bit
  • mcp23008_pin3'put - Procedure
  • mcp23008_pin3_direction'get - Function returns bit
  • mcp23008_pin3_direction'put - Procedure
  • mcp23008_pin3_polarity'get - Function returns bit
  • mcp23008_pin3_polarity'put - Procedure
  • mcp23008_pin4'get - Function returns bit
  • mcp23008_pin4'put - Procedure
  • mcp23008_pin4_direction'get - Function returns bit
  • mcp23008_pin4_direction'put - Procedure
  • mcp23008_pin4_polarity'get - Function returns bit
  • mcp23008_pin4_polarity'put - Procedure
  • mcp23008_pin5'get - Function returns bit
  • mcp23008_pin5'put - Procedure
  • mcp23008_pin5_direction'get - Function returns bit
  • mcp23008_pin5_direction'put - Procedure
  • mcp23008_pin5_polarity'get - Function returns bit
  • mcp23008_pin5_polarity'put - Procedure
  • mcp23008_pin6'get - Function returns bit
  • mcp23008_pin6'put - Procedure
  • mcp23008_pin6_direction'get - Function returns bit
  • mcp23008_pin6_direction'put - Procedure
  • mcp23008_pin6_polarity'get - Function returns bit
  • mcp23008_pin6_polarity'put - Procedure
  • mcp23008_pin7'get - Function returns bit
  • mcp23008_pin7'put - Procedure
  • mcp23008_pin7_direction'get - Function returns bit
  • mcp23008_pin7_direction'put - Procedure
  • mcp23008_pin7_polarity'get - Function returns bit
  • mcp23008_pin7_polarity'put - Procedure
  • mcp23008_port'get - Function returns byte
  • mcp23008_port'put - Procedure
  • mcp23008_port_direction'get - Function returns byte
  • mcp23008_port_direction'put - Procedure
  • mcp23008_port_polarity'get - Function returns byte
  • mcp23008_port_polarity'put - Procedure
  • mcp23008_pull_up'get - Function returns byte
  • mcp23008_pull_up'put - Procedure
  • mcp23008_pull_up0'get - Function returns bit
  • mcp23008_pull_up0'put - Procedure
  • mcp23008_pull_up1'get - Function returns bit
  • mcp23008_pull_up1'put - Procedure
  • mcp23008_pull_up2'get - Function returns bit
  • mcp23008_pull_up2'put - Procedure
  • mcp23008_pull_up3'get - Function returns bit
  • mcp23008_pull_up3'put - Procedure
  • mcp23008_pull_up4'get - Function returns bit
  • mcp23008_pull_up4'put - Procedure
  • mcp23008_pull_up5'get - Function returns bit
  • mcp23008_pull_up5'put - Procedure
  • mcp23008_pull_up6'get - Function returns bit
  • mcp23008_pull_up6'put - Procedure
  • mcp23008_pull_up7'get - Function returns bit
  • mcp23008_pull_up7'put - Procedure
  • mcp23008_set_interrupt_active_high - Procedure
  • mcp23008_set_interrupt_active_low - Procedure
  • mcp23008_set_interrupt_compare_value - Procedure
  • mcp23008_set_interrupt_control - Procedure
  • mcp23008_set_interrupt_on_change - Procedure
  • mcp23008_set_interrupt_output_driving - Procedure
  • mcp23008_set_interrupt_output_open_drain - Procedure
  • mcp23008_slew_rate - Procedure


mcp23008_get_interrupt_flags - JALlib Procedures Help

mcp23008_get_interrupt_flags JALLIB FUNCTION

Signature

function mcp23008_get_interrupt_flags() return byte is

Description

Return the interrupt flags. See datasheet for details.

Include

To use this procedure, include the library:

include mcp23008

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_mcp23008.jal

-- Title: Sample and test program for the MCP23008 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23008 8-Bit I/O Expander.
--              This device is controlled via an IIC interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23008 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include mcp23008

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23008_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23008_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23008_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23008_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23008_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23008_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23008_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23008_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23008_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23008.\r\n")

forever  loop

   -- Initialize port.
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port_polarity = ALL_DISABLED
   mcp23008_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23008_port = 0x00
   wait()
   mcp23008_port = 0xFF
   wait()
   mcp23008_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23008_latch = 0x00
   wait()
   mcp23008_latch = 0xFF
   wait()
   mcp23008_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23008_pin0 = HIGH
   wait()
   mcp23008_pin1 = HIGH
   wait()
   mcp23008_pin2 = HIGH
   wait()
   mcp23008_pin3 = HIGH
   wait()
   mcp23008_pin4 = HIGH
   wait()
   mcp23008_pin5 = HIGH
   wait()
   mcp23008_pin6 = HIGH
   wait()
   mcp23008_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23008_latch0 = LOW
   wait()
   mcp23008_latch1 = LOW
   wait()
   mcp23008_latch2 = LOW
   wait()
   mcp23008_latch3 = LOW
   wait()
   mcp23008_latch4 = LOW
   wait()
   mcp23008_latch5 = LOW
   wait()
   mcp23008_latch6 = LOW
   wait()
   mcp23008_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23008_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pin1_direction = INPUT
   mcp23008_pin2_direction = INPUT
   mcp23008_pin3_direction = INPUT
   mcp23008_pin4_direction = INPUT
   mcp23008_pin5_direction = INPUT
   mcp23008_pin6_direction = INPUT
   mcp23008_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23008_pull_up0 = ENABLED
   mcp23008_pull_up1 = ENABLED
   mcp23008_pull_up2 = ENABLED
   mcp23008_pull_up3 = ENABLED
   mcp23008_pull_up4 = ENABLED
   mcp23008_pull_up5 = ENABLED
   mcp23008_pull_up6 = ENABLED
   mcp23008_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23008_pull_up = ALL_DISABLED
   mcp23008_pin0_polarity = ENABLED
   mcp23008_pin1_polarity = ENABLED
   mcp23008_pin2_polarity = ENABLED
   mcp23008_pin3_polarity = ENABLED
   mcp23008_pin4_polarity = ENABLED
   mcp23008_pin5_polarity = ENABLED
   mcp23008_pin6_polarity = ENABLED
   mcp23008_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23008_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23008_set_interrupt_output_driving() -- Not open drain.
   mcp23008_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23008_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23008_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23008_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23008_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23008_pin7 = HIGH
   else
      mcp23008_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin1_direction = INPUT
   mcp23008_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23008_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin6 = HIGH
   else
      mcp23008_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin5 = HIGH
   else
      mcp23008_pin4 = HIGH
   end if
   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23008.jal


mcp23008_set_interrupt_active_low - JALlib Procedures Help

mcp23008_set_interrupt_active_low JALLIB PROCEDURE

Signature

procedure mcp23008_set_interrupt_active_low() is

Description

Set the interrupt polarity to active LOW.

Include

To use this procedure, include the library:

include mcp23008

Parameters

None

Return Value

None

Example

From sample file: 16f1825_mcp23008.jal

-- Title: Sample and test program for the MCP23008 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23008 8-Bit I/O Expander.
--              This device is controlled via an IIC interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23008 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include mcp23008

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23008_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23008_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23008_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23008_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23008_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23008_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23008_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23008_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23008_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23008.\r\n")

forever  loop

   -- Initialize port.
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port_polarity = ALL_DISABLED
   mcp23008_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23008_port = 0x00
   wait()
   mcp23008_port = 0xFF
   wait()
   mcp23008_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23008_latch = 0x00
   wait()
   mcp23008_latch = 0xFF
   wait()
   mcp23008_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23008_pin0 = HIGH
   wait()
   mcp23008_pin1 = HIGH
   wait()
   mcp23008_pin2 = HIGH
   wait()
   mcp23008_pin3 = HIGH
   wait()
   mcp23008_pin4 = HIGH
   wait()
   mcp23008_pin5 = HIGH
   wait()
   mcp23008_pin6 = HIGH
   wait()
   mcp23008_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23008_latch0 = LOW
   wait()
   mcp23008_latch1 = LOW
   wait()
   mcp23008_latch2 = LOW
   wait()
   mcp23008_latch3 = LOW
   wait()
   mcp23008_latch4 = LOW
   wait()
   mcp23008_latch5 = LOW
   wait()
   mcp23008_latch6 = LOW
   wait()
   mcp23008_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23008_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pin1_direction = INPUT
   mcp23008_pin2_direction = INPUT
   mcp23008_pin3_direction = INPUT
   mcp23008_pin4_direction = INPUT
   mcp23008_pin5_direction = INPUT
   mcp23008_pin6_direction = INPUT
   mcp23008_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23008_pull_up0 = ENABLED
   mcp23008_pull_up1 = ENABLED
   mcp23008_pull_up2 = ENABLED
   mcp23008_pull_up3 = ENABLED
   mcp23008_pull_up4 = ENABLED
   mcp23008_pull_up5 = ENABLED
   mcp23008_pull_up6 = ENABLED
   mcp23008_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23008_pull_up = ALL_DISABLED
   mcp23008_pin0_polarity = ENABLED
   mcp23008_pin1_polarity = ENABLED
   mcp23008_pin2_polarity = ENABLED
   mcp23008_pin3_polarity = ENABLED
   mcp23008_pin4_polarity = ENABLED
   mcp23008_pin5_polarity = ENABLED
   mcp23008_pin6_polarity = ENABLED
   mcp23008_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23008_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23008_set_interrupt_output_driving() -- Not open drain.
   mcp23008_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23008_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23008_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23008_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23008_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23008_pin7 = HIGH
   else
      mcp23008_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin1_direction = INPUT
   mcp23008_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23008_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin6 = HIGH
   else
      mcp23008_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin5 = HIGH
   else
      mcp23008_pin4 = HIGH
   end if
   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23008.jal


mcp23008_set_interrupt_compare_value - JALlib Procedures Help

mcp23008_set_interrupt_compare_value JALLIB PROCEDURE

Signature

procedure mcp23008_set_interrupt_compare_value(byte in value) is

Description

Set interrupt compare value. See datasheet for details.

Include

To use this procedure, include the library:

include mcp23008

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f1825_mcp23008.jal

-- Title: Sample and test program for the MCP23008 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23008 8-Bit I/O Expander.
--              This device is controlled via an IIC interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23008 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include mcp23008

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23008_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23008_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23008_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23008_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23008_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23008_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23008_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23008_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23008_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23008.\r\n")

forever  loop

   -- Initialize port.
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port_polarity = ALL_DISABLED
   mcp23008_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23008_port = 0x00
   wait()
   mcp23008_port = 0xFF
   wait()
   mcp23008_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23008_latch = 0x00
   wait()
   mcp23008_latch = 0xFF
   wait()
   mcp23008_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23008_pin0 = HIGH
   wait()
   mcp23008_pin1 = HIGH
   wait()
   mcp23008_pin2 = HIGH
   wait()
   mcp23008_pin3 = HIGH
   wait()
   mcp23008_pin4 = HIGH
   wait()
   mcp23008_pin5 = HIGH
   wait()
   mcp23008_pin6 = HIGH
   wait()
   mcp23008_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23008_latch0 = LOW
   wait()
   mcp23008_latch1 = LOW
   wait()
   mcp23008_latch2 = LOW
   wait()
   mcp23008_latch3 = LOW
   wait()
   mcp23008_latch4 = LOW
   wait()
   mcp23008_latch5 = LOW
   wait()
   mcp23008_latch6 = LOW
   wait()
   mcp23008_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23008_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pin1_direction = INPUT
   mcp23008_pin2_direction = INPUT
   mcp23008_pin3_direction = INPUT
   mcp23008_pin4_direction = INPUT
   mcp23008_pin5_direction = INPUT
   mcp23008_pin6_direction = INPUT
   mcp23008_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23008_pull_up0 = ENABLED
   mcp23008_pull_up1 = ENABLED
   mcp23008_pull_up2 = ENABLED
   mcp23008_pull_up3 = ENABLED
   mcp23008_pull_up4 = ENABLED
   mcp23008_pull_up5 = ENABLED
   mcp23008_pull_up6 = ENABLED
   mcp23008_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23008_pull_up = ALL_DISABLED
   mcp23008_pin0_polarity = ENABLED
   mcp23008_pin1_polarity = ENABLED
   mcp23008_pin2_polarity = ENABLED
   mcp23008_pin3_polarity = ENABLED
   mcp23008_pin4_polarity = ENABLED
   mcp23008_pin5_polarity = ENABLED
   mcp23008_pin6_polarity = ENABLED
   mcp23008_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23008_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23008_set_interrupt_output_driving() -- Not open drain.
   mcp23008_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23008_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23008_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23008_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23008_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23008_pin7 = HIGH
   else
      mcp23008_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin1_direction = INPUT
   mcp23008_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23008_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin6 = HIGH
   else
      mcp23008_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin5 = HIGH
   else
      mcp23008_pin4 = HIGH
   end if
   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23008.jal


mcp23008_set_interrupt_control - JALlib Procedures Help

mcp23008_set_interrupt_control JALLIB PROCEDURE

Signature

procedure mcp23008_set_interrupt_control(byte in value) is

Description

Set the interrupt control value. See datasheet for details.

Include

To use this procedure, include the library:

include mcp23008

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f1825_mcp23008.jal

-- Title: Sample and test program for the MCP23008 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23008 8-Bit I/O Expander.
--              This device is controlled via an IIC interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23008 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include mcp23008

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23008_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23008_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23008_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23008_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23008_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23008_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23008_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23008_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23008_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23008.\r\n")

forever  loop

   -- Initialize port.
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port_polarity = ALL_DISABLED
   mcp23008_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23008_port = 0x00
   wait()
   mcp23008_port = 0xFF
   wait()
   mcp23008_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23008_latch = 0x00
   wait()
   mcp23008_latch = 0xFF
   wait()
   mcp23008_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23008_pin0 = HIGH
   wait()
   mcp23008_pin1 = HIGH
   wait()
   mcp23008_pin2 = HIGH
   wait()
   mcp23008_pin3 = HIGH
   wait()
   mcp23008_pin4 = HIGH
   wait()
   mcp23008_pin5 = HIGH
   wait()
   mcp23008_pin6 = HIGH
   wait()
   mcp23008_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23008_latch0 = LOW
   wait()
   mcp23008_latch1 = LOW
   wait()
   mcp23008_latch2 = LOW
   wait()
   mcp23008_latch3 = LOW
   wait()
   mcp23008_latch4 = LOW
   wait()
   mcp23008_latch5 = LOW
   wait()
   mcp23008_latch6 = LOW
   wait()
   mcp23008_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23008_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pin1_direction = INPUT
   mcp23008_pin2_direction = INPUT
   mcp23008_pin3_direction = INPUT
   mcp23008_pin4_direction = INPUT
   mcp23008_pin5_direction = INPUT
   mcp23008_pin6_direction = INPUT
   mcp23008_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23008_pull_up0 = ENABLED
   mcp23008_pull_up1 = ENABLED
   mcp23008_pull_up2 = ENABLED
   mcp23008_pull_up3 = ENABLED
   mcp23008_pull_up4 = ENABLED
   mcp23008_pull_up5 = ENABLED
   mcp23008_pull_up6 = ENABLED
   mcp23008_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23008_pull_up = ALL_DISABLED
   mcp23008_pin0_polarity = ENABLED
   mcp23008_pin1_polarity = ENABLED
   mcp23008_pin2_polarity = ENABLED
   mcp23008_pin3_polarity = ENABLED
   mcp23008_pin4_polarity = ENABLED
   mcp23008_pin5_polarity = ENABLED
   mcp23008_pin6_polarity = ENABLED
   mcp23008_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23008_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23008_set_interrupt_output_driving() -- Not open drain.
   mcp23008_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23008_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23008_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23008_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23008_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23008_pin7 = HIGH
   else
      mcp23008_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin1_direction = INPUT
   mcp23008_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23008_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin6 = HIGH
   else
      mcp23008_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin5 = HIGH
   else
      mcp23008_pin4 = HIGH
   end if
   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23008.jal


mcp23008_set_interrupt_on_change - JALlib Procedures Help

mcp23008_set_interrupt_on_change JALLIB PROCEDURE

Signature

procedure mcp23008_set_interrupt_on_change(byte in value) is

Description

Set interrupt on change register. Bit set is ENABLE, bit clear is DISABLE.
See datasheet for details.

Include

To use this procedure, include the library:

include mcp23008

Parameters

  • value - byte in

Return Value

None

Example

From sample file: 16f1825_mcp23008.jal

-- Title: Sample and test program for the MCP23008 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23008 8-Bit I/O Expander.
--              This device is controlled via an IIC interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23008 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include mcp23008

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23008_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23008_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23008_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23008_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23008_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23008_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23008_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23008_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23008_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23008.\r\n")

forever  loop

   -- Initialize port.
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port_polarity = ALL_DISABLED
   mcp23008_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23008_port = 0x00
   wait()
   mcp23008_port = 0xFF
   wait()
   mcp23008_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23008_latch = 0x00
   wait()
   mcp23008_latch = 0xFF
   wait()
   mcp23008_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23008_pin0 = HIGH
   wait()
   mcp23008_pin1 = HIGH
   wait()
   mcp23008_pin2 = HIGH
   wait()
   mcp23008_pin3 = HIGH
   wait()
   mcp23008_pin4 = HIGH
   wait()
   mcp23008_pin5 = HIGH
   wait()
   mcp23008_pin6 = HIGH
   wait()
   mcp23008_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23008_latch0 = LOW
   wait()
   mcp23008_latch1 = LOW
   wait()
   mcp23008_latch2 = LOW
   wait()
   mcp23008_latch3 = LOW
   wait()
   mcp23008_latch4 = LOW
   wait()
   mcp23008_latch5 = LOW
   wait()
   mcp23008_latch6 = LOW
   wait()
   mcp23008_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23008_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pin1_direction = INPUT
   mcp23008_pin2_direction = INPUT
   mcp23008_pin3_direction = INPUT
   mcp23008_pin4_direction = INPUT
   mcp23008_pin5_direction = INPUT
   mcp23008_pin6_direction = INPUT
   mcp23008_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23008_pull_up0 = ENABLED
   mcp23008_pull_up1 = ENABLED
   mcp23008_pull_up2 = ENABLED
   mcp23008_pull_up3 = ENABLED
   mcp23008_pull_up4 = ENABLED
   mcp23008_pull_up5 = ENABLED
   mcp23008_pull_up6 = ENABLED
   mcp23008_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23008_pull_up = ALL_DISABLED
   mcp23008_pin0_polarity = ENABLED
   mcp23008_pin1_polarity = ENABLED
   mcp23008_pin2_polarity = ENABLED
   mcp23008_pin3_polarity = ENABLED
   mcp23008_pin4_polarity = ENABLED
   mcp23008_pin5_polarity = ENABLED
   mcp23008_pin6_polarity = ENABLED
   mcp23008_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23008_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23008_set_interrupt_output_driving() -- Not open drain.
   mcp23008_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23008_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23008_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23008_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23008_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23008_pin7 = HIGH
   else
      mcp23008_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin1_direction = INPUT
   mcp23008_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23008_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin6 = HIGH
   else
      mcp23008_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin5 = HIGH
   else
      mcp23008_pin4 = HIGH
   end if
   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23008.jal


mcp23008_set_interrupt_output_driving - JALlib Procedures Help

mcp23008_set_interrupt_output_driving JALLIB PROCEDURE

Signature

procedure mcp23008_set_interrupt_output_driving() is

Description

Set the interrupt output to driving.

Include

To use this procedure, include the library:

include mcp23008

Parameters

None

Return Value

None

Example

From sample file: 16f1825_mcp23008.jal

-- Title: Sample and test program for the MCP23008 8-bit I/O Expander.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and test program showing how to use MCP23008 8-Bit I/O Expander.
--              This device is controlled via an IIC interface.
--              For testing LEDs must be connected to each pin. The interrupt pin of the
--              MCP23008 has to be connected to the INT pin of the PIC. Next to that the
--              serial interface is used to show status and wait for a keypress.
--              Four test can be enabled/disabled. The following tests can be run:
--              -) Test the the port as output.
--              -) Test the port as input, with and without pull-up resistors
--              -) Test the interrupt functionality
--
-- Sources: Microchip MCP23008/MCP23008 8-bit I/O Expander with serial interface.
--          Datasheet DS20001919F.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial_data is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include mcp23008

-- Variables.
var byte data
var bit external_interrupt, dummy

-- Interrupt procedure. Interrupt is connected to external interrupt (INT).
-- We cannot read from the register in the interrupt routine so we set a flag.
procedure mcp23008_interrupt() is
   pragma interrupt

   if INTCON_INTF then
      INTCON_INTF = FALSE
      external_interrupt = TRUE
   end if

end procedure

-- Wait for a key pressed.
function key_is_pressed() return bit is

   var byte dummy
   var bit pressed = FALSE

   if serial_hw_data_available() then
      -- Swallow all data while available.
      while serial_hw_data_available() loop
         dummy = serial_data
         delay_1ms(200) -- Time to receive more data.
      end loop
      pressed = TRUE
   end if

   return pressed

end function

procedure wait() is

   delay_1ms(500)

end procedure

; Print the status of all individual input pins.
procedure print_pin_status() is

   if mcp23008_pin0 then
      print_string(serial_data, "Pin 0 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 0 is LOW.\r\n")
   end if
    if mcp23008_pin1 then
      print_string(serial_data, "Pin 1 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 1 is LOW.\r\n")
   end if
   if mcp23008_pin2 then
      print_string(serial_data, "Pin 2 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 2 is LOW.\r\n")
   end if
   if mcp23008_pin3 then
      print_string(serial_data, "Pin 3 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 3 is LOW.\r\n")
   end if
   if mcp23008_pin4 then
      print_string(serial_data, "Pin 4 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 4 is LOW.\r\n")
   end if
   if mcp23008_pin5 then
      print_string(serial_data, "Pin 5 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 5 is LOW.\r\n")
   end if
   if mcp23008_pin6 then
      print_string(serial_data, "Pin 6 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 6 is LOW.\r\n")
   end if
   if mcp23008_pin7 then
      print_string(serial_data, "Pin 7 is HIGH.\r\n")
   else
      print_string(serial_data, "Pin 7 is LOW.\r\n")
   end if
   print_crlf(serial_data)
end procedure

-- Main program starts here.

-- Test definitions which can be enabled or disabled by commenting out the line.
const TEST_1 = TRUE -- Testing pins as output with LEDs.
const TEST_2 = TRUE -- Testing pins as input.
const TEST_3 = TRUE -- Testing the Interrupt.

-- Enable external interrupt for testing.
INTCON_INTE = TRUE
INTCON_INTF = FALSE
OPTION_REG_INTEDG = FALSE -- Falling edge.
INTCON_GIE = TRUE

print_crlf(serial_data)
print_string(serial_data, "Test program for the MCP23008.\r\n")

forever  loop

   -- Initialize port.
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port_polarity = ALL_DISABLED
   mcp23008_pull_up = ALL_DISABLED

if defined(TEST_1) then
   print_string(serial_data, "All LEDs set to output and put the LEDs on and off twice.\r\n")
   -- Set the port value.
   mcp23008_port = 0x00
   wait()
   mcp23008_port = 0xFF
   wait()
   mcp23008_port = 0x00
   wait()

   -- Set the latch value, same behavior as port.
   mcp23008_latch = 0x00
   wait()
   mcp23008_latch = 0xFF
   wait()
   mcp23008_latch = 0x00
   wait()

   -- Set individual port pins.
   print_string(serial_data, "Individual pins on.\r\n")
   mcp23008_pin0 = HIGH
   wait()
   mcp23008_pin1 = HIGH
   wait()
   mcp23008_pin2 = HIGH
   wait()
   mcp23008_pin3 = HIGH
   wait()
   mcp23008_pin4 = HIGH
   wait()
   mcp23008_pin5 = HIGH
   wait()
   mcp23008_pin6 = HIGH
   wait()
   mcp23008_pin7 = HIGH
   wait()

   -- Reset individual latch pins, same behavior as port.
   print_string(serial_data, "Individual pins off.\r\n")
   mcp23008_latch0 = LOW
   wait()
   mcp23008_latch1 = LOW
   wait()
   mcp23008_latch2 = LOW
   wait()
   mcp23008_latch3 = LOW
   wait()
   mcp23008_latch4 = LOW
   wait()
   mcp23008_latch5 = LOW
   wait()
   mcp23008_latch6 = LOW
   wait()
   mcp23008_latch7 = LOW
   wait()
   print_crlf(serial_data)
   print_crlf(serial_data)
end if

if defined(TEST_2) then
   mcp23008_port = 0xFF -- All LEDs will be on.
   -- Set individual pins to input and read 8 times. LEDs will turn off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pin1_direction = INPUT
   mcp23008_pin2_direction = INPUT
   mcp23008_pin3_direction = INPUT
   mcp23008_pin4_direction = INPUT
   mcp23008_pin5_direction = INPUT
   mcp23008_pin6_direction = INPUT
   mcp23008_pin7_direction = INPUT
   -- Note that since inputs are floating, values also float.
   while !key_is_pressed() loop
      print_string(serial_data, "Individual pins set to input.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

   -- Set individual pins to pull-up. LEDs light up a little bit.
   mcp23008_pull_up0 = ENABLED
   mcp23008_pull_up1 = ENABLED
   mcp23008_pull_up2 = ENABLED
   mcp23008_pull_up3 = ENABLED
   mcp23008_pull_up4 = ENABLED
   mcp23008_pull_up5 = ENABLED
   mcp23008_pull_up6 = ENABLED
   mcp23008_pull_up7 = ENABLED
   -- Now inputs should all be HIGH but if LEDs are connected this can differ.
   while !key_is_pressed() loop
      print_string(serial_data, "Enabling pull-up resistors. LEDs may light up a bit.\r\n")
      print_string(serial_data, "Port pins can be random, depending on the LEDs connnected.\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to skip.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   print_crlf(serial_data)

  -- Change input polarity of individual pins. A HIGH on the input will be shown as LOW.
   mcp23008_pull_up = ALL_DISABLED
   mcp23008_pin0_polarity = ENABLED
   mcp23008_pin1_polarity = ENABLED
   mcp23008_pin2_polarity = ENABLED
   mcp23008_pin3_polarity = ENABLED
   mcp23008_pin4_polarity = ENABLED
   mcp23008_pin5_polarity = ENABLED
   mcp23008_pin6_polarity = ENABLED
   mcp23008_pin7_polarity = ENABLED
   while !key_is_pressed() loop
      print_string(serial_data, "Changing input polarity to inverted (pull-up is disabled).\r\n")
      print_string(serial_data, "Connect input to VCC or GND. Press any key to continue.\r\n")
      print_string(serial_data, "Port value is: ")
      print_byte_bin(serial_data, mcp23008_port)
      print_crlf(serial_data)
      print_pin_status()
      delay_1s(1)
   end loop
   -- Restore to non-inverted input.
   mcp23008_port_polarity = ALL_DISABLED
   print_crlf(serial_data)
end if

if defined(TEST_3) then
   -- Testing the interrupts.
   print_string(serial_data, "First disconnect the LED on pin 0 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting Interrupt on change op pin 0.\r\n")
   print_string(serial_data, "If pin 0 changes state (to LOW) pin 7 must go HIGH, pin 6 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port_direction = ALL_OUTPUT
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin0_direction = INPUT
   mcp23008_pull_up0 = ENABLED -- This will make the input pin high.
   mcp23008_set_interrupt_output_driving() -- Not open drain.
   mcp23008_set_interrupt_active_low()     -- Triggered on falling edge.
   dummy = mcp23008_pin0  -- Clear any pending interrupt on this pin.
   external_interrupt = FALSE
   mcp23008_set_interrupt_control(0x00)          -- Interrupt on change compared to previous value.
   mcp23008_set_interrupt_on_change(0b0000_0001) -- Interrupt on change enabled for pin 0.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 6 HIGH instead of pin 7.
   if (mcp23008_get_interrupt_flags() & 0b0000_0001) != 0 then
      mcp23008_pin7 = HIGH
   else
      mcp23008_pin6 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin0 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "First disconnect the LED on pin 1 and press any key.\r\n")
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
   print_string(serial_data, "Setting interrupt compare on change op pin 1.\r\n")
   print_string(serial_data, "If pin 1 is LOW (HIGH should not do anything) pin 6 must go HIGH, pin 5 HIGH is error.\r\n")
   print_string(serial_data, "When done press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   mcp23008_pin1_direction = INPUT
   mcp23008_pull_up1 = ENABLED -- This will make the input high.
   dummy = mcp23008_pin1 -- Clear any pending interrupt on pin 1.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0010) -- Compare pin with value 1. If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_control(0b0000_0010)       -- Interrupt on compare for pin 1.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- Interrupt on change enabled for pin 1.
   -- Wait for it.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 1, if not we make pin 5 HIGH, instead of pin 6..
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin6 = HIGH
   else
      mcp23008_pin5 = HIGH
   end if
   print_crlf(serial_data)

   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   dummy = mcp23008_pin1 -- Clear any pending interrupt.
   while !key_is_pressed() loop end loop
   print_string(serial_data, "Setting Interrupt compare value 1 on pin 1.\r\n")
   print_string(serial_data, "If pin is 1 HIGH (which is the case due to pull-up) pin 5 must go HIGH immediately, pin 4 HIGH is error.\r\n")
   print_string(serial_data, "Press any key for next step.\r\n")
   mcp23008_port = 0x00 -- All LEDs off.
   external_interrupt = FALSE
   mcp23008_set_interrupt_compare_value(0b0000_0000) -- Compare pin with value 0.  If it differs it will trigger the interrupt.
   mcp23008_set_interrupt_on_change(0b0000_0010)     -- This will immediately trigger the interrupt since the pin is HIGH and the value is LOW.
   while !external_interrupt loop end loop
   -- It must be the interrupt generated by pin 0, if not we make pin 4 HIGH, instead of pin 5.
   if (mcp23008_get_interrupt_flags & 0b0000_0010) != 0 then
      mcp23008_pin5 = HIGH
   else
      mcp23008_pin4 = HIGH
   end if
   mcp23008_set_interrupt_on_change(ALL_DISABLED) -- Disable the interrupt.
   while !key_is_pressed() loop end loop
   print_crlf(serial_data)
end if

   print_string(serial_data, "All done. Restart test.\r\n")
   print_crlf(serial_data)

end loop

Generated by JALlib CHM Help System | Source: mcp23008.jal


memory_pointer0.jal - JALLIB Library Documentation

memory_pointer0.jal JALLIB LIBRARY

Title

Memory Pointers (indirect registers)

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2020, all rights reserved., Adapted-by: Rob Jansen

Compiler

>=2.5r3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Memory Pointers. For fast sequential array read/writes.

Notes

If POSTINC0 is not supported, another method is used to provide the
same functionality. Your code should check if defined(mem_pointer0)
before using, otherwise use another method of doing whatever it is
your trying to do. Only works on var arrays not const arrays.

------------------------------------------------------------------------------
WHEREIS() is now supported by the compiler, please use WHEREIS() instead.
Get the address of an array variable.
------------------------------------------------------------------------------

Routines

  • mem_pointer0 - Function returns word
  • mem_pointer0 - Function returns dword
  • mem_pointer0'get - Function returns byte
  • mem_pointer0'get - Function returns word
  • mem_pointer0'get - Function returns dword
  • mem_pointer0'put - Procedure
  • mem_pointer0'put - Procedure
  • mem_pointer0'put - Procedure
  • mem_whereis_array - Function returns word


memory_pointer1.jal - JALLIB Library Documentation

memory_pointer1.jal JALLIB LIBRARY

Title

Memory Pointers (indirect registers)

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2020, all rights reserved. f, Adapted-by: Rob Jansen

Compiler

>=2.5r3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Memory Pointers. For fast sequential array read/writes.

Notes

If POSTINC1 is not supported, another method is used to provide the
same functionality. Your code should check if defined(mem_pointer1)
before using, otherwise use another method of doing whatever it is
your trying to do. Only works on var arrays not const arrays.

------------------------------------------------------------------------------
WHEREIS() is now supported by the compiler, please use WHEREIS() instead.
Get the address of an array variable.
------------------------------------------------------------------------------

Routines

  • mem_pointer1 - Function returns word
  • mem_pointer1 - Function returns dword
  • mem_pointer1'get - Function returns byte
  • mem_pointer1'get - Function returns word
  • mem_pointer1'get - Function returns dword
  • mem_pointer1'put - Procedure
  • mem_pointer1'put - Procedure
  • mem_pointer1'put - Procedure
  • mem_whereis_array - Function returns word


memory_pointer2.jal - JALLIB Library Documentation

memory_pointer2.jal JALLIB LIBRARY

Title

Memory Pointers (indirect registers)

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2020, all rights reserved., Adapted-by: Rob Jansen

Compiler

>=2.5r3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Memory Pointers. For fast sequential array read/writes.

Notes

If POSTINC2 is not supported, another method is used to provide the
same functionality. Your code should check if defined(mem_pointer2)
before using, otherwise use another method of doing whatever it is
your trying to do. Only works on var arrays not const arrays.

------------------------------------------------------------------------------
WHEREIS() is now supported by the compiler, please use WHEREIS() instead.
Get the address of an array variable.
------------------------------------------------------------------------------

Routines

  • mem_pointer2 - Function returns word
  • mem_pointer2 - Function returns dword
  • mem_pointer2'get - Function returns byte
  • mem_pointer2'get - Function returns word
  • mem_pointer2'get - Function returns dword
  • mem_pointer2'put - Procedure
  • mem_pointer2'put - Procedure
  • mem_pointer2'put - Procedure
  • mem_whereis_array - Function returns word


Message generating - JAL Language Syntax Reference

Message generating JALV2 SYNTAX

Description

The following keywords generate a message, just as if it came directly from the compiler. Each is followed by a string which will be displayed as part of the message.

Generated by JAL Syntax Documentation System | Source: DITA


minix_cat - JALlib Procedures Help

minix_cat JALLIB PROCEDURE

Signature

procedure minix_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs_cmd

Parameters

  • filename[] - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs_cmd.jal


minix_cd - JALlib Procedures Help

minix_cd JALLIB PROCEDURE

Signature

procedure minix_cd(byte in dirname[MINIX_MAX_FILENANE_LEN]) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs

Parameters

  • dirname[] - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_close - JALlib Procedures Help

minix_close JALLIB PROCEDURE

Signature

procedure minix_close() is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_read.jal

-- Title: Minix FS sample showing how to read file's content
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read file's content. This requires
-- to open a file, read some content, possibly seek (move) to a specific
-- location and, don't forget, close the file.
-- .
-- MinixFS uses some kind of file descriptor to access file, in order to know
-- current state, etc... Note there's only one file description available in
-- current MinixFS implementation.
-- .
-- This sample is based on a data set, available here:
-- http://code.google.com/p/jaluino/source/browse/trunk/tests/minix_data.tar.bz2
-- You can use this dataset to perform tests. It contains several files with
-- very specifc size, I used it to develop and test MinixFS, and this is a great
-- source of data to understand how MinixFS works.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  enabled     -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs

-- We're going to read data from file2K. This files has the following
-- structure:
--    "START1111....111NEXT2222....2222END"
--     ^----------------^^---------------^
--          1 block           1 block
--
-- Note the link between the two blocks: "NE" then "XT"

-- Here we go !

-- define which file we're going to open
-- minix_open() will expect a string of 30 chars
-- "file2K" has 6 chars, so either ignore the warning claiming
-- "fewer initializers than expected", or fill in extra space chars
-- Finally, because a filename can fit anywhere between 1 or 30 chars
-- we need to use NULL-terminated string in order MinixFS to know
-- where the filename fits
-- PS: I don't like warnings so I added extra padding chars
const byte myfile[MINIX_MAX_FILENANE_LEN] = "file2K\0                       "
minix_open(myfile,MINIX_MODE_READ)

-- let's read the "START"
for 4 loop
   serial_hw_data = minix_read()
end loop
-- can you see "START" on your serial link ?
print_crlf(serial_hw_data)

-- now let've move near the end of the first block
minix_seek(1022)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should give "NE"
serial_hw_data = minix_read() -- we moved to the 2nd block !
serial_hw_data = minix_read()
-- should give "XT"
print_crlf(serial_hw_data)

-- Now let's move to the end of file
minix_seek(2045)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should print "END"
print_crlf(serial_hw_data)

-- where are we within the file ?
-- well, what's the size ?
-- let's access some information from File Descriptor
-- and inode records
const byte sz[] = "Size: "
print_string(serial_hw_data,sz)
print_dword_dec(serial_hw_data,minix_filefd.inode.filesize)
print_crlf(serial_hw_data)
-- and how much did we read ?
const byte rd[] = "Read: "
print_string(serial_hw_data,rd)
print_dword_dec(serial_hw_data,minix_filefd.read)
print_crlf(serial_hw_data)
-- alright, this means there's nothing to read further ?
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- => print nothing !
-- ok, don't forget to close file. If you access another file
-- without closing previous, you may just get stuck ("crash")
minix_close()

print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

-- Sounds like we have everything to implement "cat" command :)
-- note: minix v2have max filename lenght = 30
procedure my_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is
   minix_open(filename,MINIX_MODE_READ)
   while minix_filefd.read != minix_filefd.inode.filesize loop
      serial_hw_data = minix_read()
   end loop
   minix_close()
end procedure
-- (you can find this procedure in minixfs_cmd.jal)

my_cat(myfile)
print_crlf(serial_hw_data)

-- enough, let's do nothing...
forever loop
end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_dev_cat - JALlib Procedures Help

minix_dev_cat JALLIB PROCEDURE

Signature

procedure minix_dev_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs_cmd

Parameters

  • filename[] - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs_cmd.jal


minix_dev_print_error - JALlib Procedures Help

minix_dev_print_error JALLIB PROCEDURE

Signature

procedure minix_dev_print_error() is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs_cmd

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs_cmd.jal


minix_dev_print_super_block - JAL Language Syntax Reference

minix_dev_print_super_block SYNTAX

Description:
As a (optional) bonus, this library provides useful commands while -- dealing with MinixFS, like printing file's content, print super block, etc... -- Some require prior definition of "minix_print_carrier" pseudo-var definition, -- used to actually display data (typically serial_hw_data, usb_serial_data, etc...) -- If not defined, others can still be used. -- Careful, using these commands can cost a lot of resources... -- if defined(minix_print_carrier) then include print -- Messages

Generated by JAL Syntax Documentation System | Source: DITA


minix_init - JALlib Procedures Help

minix_init JALLIB PROCEDURE

Signature

procedure minix_init(bit in check) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs

Parameters

  • check - bit in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_ls - JALlib Procedures Help

minix_ls JALLIB PROCEDURE

Signature

procedure minix_ls(byte in filename[MINIX_MAX_FILENANE_LEN]) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs_cmd

Parameters

  • filename[] - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs_cmd.jal


minix_open - JALlib Procedures Help

minix_open JALLIB PROCEDURE

Signature

procedure minix_open(byte in filename[MINIX_MAX_FILENANE_LEN],byte in mode) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs

Parameters

  • filename[] - byte in
  • mode - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_read.jal

-- Title: Minix FS sample showing how to read file's content
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read file's content. This requires
-- to open a file, read some content, possibly seek (move) to a specific
-- location and, don't forget, close the file.
-- .
-- MinixFS uses some kind of file descriptor to access file, in order to know
-- current state, etc... Note there's only one file description available in
-- current MinixFS implementation.
-- .
-- This sample is based on a data set, available here:
-- http://code.google.com/p/jaluino/source/browse/trunk/tests/minix_data.tar.bz2
-- You can use this dataset to perform tests. It contains several files with
-- very specifc size, I used it to develop and test MinixFS, and this is a great
-- source of data to understand how MinixFS works.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  enabled     -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs

-- We're going to read data from file2K. This files has the following
-- structure:
--    "START1111....111NEXT2222....2222END"
--     ^----------------^^---------------^
--          1 block           1 block
--
-- Note the link between the two blocks: "NE" then "XT"

-- Here we go !

-- define which file we're going to open
-- minix_open() will expect a string of 30 chars
-- "file2K" has 6 chars, so either ignore the warning claiming
-- "fewer initializers than expected", or fill in extra space chars
-- Finally, because a filename can fit anywhere between 1 or 30 chars
-- we need to use NULL-terminated string in order MinixFS to know
-- where the filename fits
-- PS: I don't like warnings so I added extra padding chars
const byte myfile[MINIX_MAX_FILENANE_LEN] = "file2K\0                       "
minix_open(myfile,MINIX_MODE_READ)

-- let's read the "START"
for 4 loop
   serial_hw_data = minix_read()
end loop
-- can you see "START" on your serial link ?
print_crlf(serial_hw_data)

-- now let've move near the end of the first block
minix_seek(1022)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should give "NE"
serial_hw_data = minix_read() -- we moved to the 2nd block !
serial_hw_data = minix_read()
-- should give "XT"
print_crlf(serial_hw_data)

-- Now let's move to the end of file
minix_seek(2045)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should print "END"
print_crlf(serial_hw_data)

-- where are we within the file ?
-- well, what's the size ?
-- let's access some information from File Descriptor
-- and inode records
const byte sz[] = "Size: "
print_string(serial_hw_data,sz)
print_dword_dec(serial_hw_data,minix_filefd.inode.filesize)
print_crlf(serial_hw_data)
-- and how much did we read ?
const byte rd[] = "Read: "
print_string(serial_hw_data,rd)
print_dword_dec(serial_hw_data,minix_filefd.read)
print_crlf(serial_hw_data)
-- alright, this means there's nothing to read further ?
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- => print nothing !
-- ok, don't forget to close file. If you access another file
-- without closing previous, you may just get stuck ("crash")
minix_close()

print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

-- Sounds like we have everything to implement "cat" command :)
-- note: minix v2have max filename lenght = 30
procedure my_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is
   minix_open(filename,MINIX_MODE_READ)
   while minix_filefd.read != minix_filefd.inode.filesize loop
      serial_hw_data = minix_read()
   end loop
   minix_close()
end procedure
-- (you can find this procedure in minixfs_cmd.jal)

my_cat(myfile)
print_crlf(serial_hw_data)

-- enough, let's do nothing...
forever loop
end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_open_block - JALlib Procedures Help

minix_open_block JALLIB PROCEDURE

Signature

procedure minix_open_block(dword in num) is

Description

move to block number and open read access on underlying storage

Include

To use this procedure, include the library:

include minixfs

Parameters

  • num - dword in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_openi - JALlib Procedures Help

minix_openi JALLIB PROCEDURE

Signature

procedure minix_openi(word in inode_num,byte in mode) is

Description

No description available.

Include

To use this procedure, include the library:

include minixfs

Parameters

  • inode_num - word in
  • mode - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_readi.jal

-- Title: Minix FS sample showing how to read file's content from an inode number
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample is a rough duplication of "*_sd_card_minix_read.jal" sample.
-- Please also refer to this sample. The main difference between these is about
-- either using a filename or an inode number to access a file. This really is
-- the only difference...
-- .
-- What are the benefits ? Directly using inode number saves a lot of resources:
-- (using -no-variable-reuse -const-detect as compiler arguments)
-- * 18f27j53_sd_card_minix_read.jal:
-- .   Code area: 10798 of 131064 used (bytes)
-- .   Data area: 1033 of 3664 used
-- .   Hardware stack depth 14 of 31
-- .
-- * 18f27j53_sd_card_minix_readi.jal:
-- .   Code area: 9354 of 131064 used (bytes)
-- .   Data area: 872 of 3664 used
-- .   Hardware stack depth 11 of 31
-- .
-- This sample is based on a data set, available here:
-- http://code.google.com/p/jaluino/source/browse/trunk/tests/minix_data.tar.bz2
-- You can use this dataset to perform tests. It contains several files with
-- very specifc size, I used it to develop and test MinixFS, and this is a great
-- source of data to understand how MinixFS works.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs

-- We're going to read data from file2K. This files has the following
-- structure:
--    "START1111....111NEXT2222....2222END"
--     ^----------------^^---------------^
--          1 block           1 block
--
-- Note the link between the two blocks: "NE" then "XT"

-- Here we go !

-- define which file we're going to open. This time, we specify
-- an inode number (so you first have to know it). If you're using
-- dataset, and properly init your Minix filesystem (from scratch)
-- file2K will have inode number 5 (use "ls -li" under Linux in order
-- to know inode number)
-- We'll use "i" versions, taking an "i"node number (minix_open => minix_openi)
minix_openi(5,MINIX_MODE_READ)

-- let's read the "START"
for 4 loop
   serial_hw_data = minix_read()
end loop
-- can you see "START" on your serial link ?
print_crlf(serial_hw_data)

-- now let've move near the end of the first block
minix_seek(1022)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should give "NE"
serial_hw_data = minix_read() -- we moved to the 2nd block !
serial_hw_data = minix_read()
-- should give "XT"
print_crlf(serial_hw_data)

-- Now let's move to the end of file
minix_seek(2045)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should print "END"
print_crlf(serial_hw_data)

-- where are we within the file ?
-- well, what's the size ?
-- let's access some information from File Descriptor
-- and inode records
const byte sz[] = "Size: "
print_string(serial_hw_data,sz)
print_dword_dec(serial_hw_data,minix_filefd.inode.filesize)
print_crlf(serial_hw_data)
-- and how much did we read ?
const byte rd[] = "Read: "
print_string(serial_hw_data,rd)
print_dword_dec(serial_hw_data,minix_filefd.read)
print_crlf(serial_hw_data)
-- alright, this means there's nothing to read further ?
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- => print nothing !
-- ok, don't forget to close file. If you access another file
-- without closing previous, you may just get stuck ("crash")
minix_close()

print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

-- Sounds like we have everything to implement "cat" command :)
procedure my_cat(byte in num) is
   minix_openi(num,MINIX_MODE_READ)
   while minix_filefd.read != minix_filefd.inode.filesize loop
      serial_hw_data = minix_read()
   end loop
   minix_close()
end procedure
-- (you can find this procedure in minixfs_cmd.jal)

my_cat(5)
print_crlf(serial_hw_data)

-- enough, let's do nothing...
forever loop
end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_read - JALlib Procedures Help

minix_read JALLIB FUNCTION

Signature

function minix_read() return byte is

Description

Read bytes from file descriptor.
Walk over memory zones given, returning content
byte by byte. firt walk over direct zones, then
swith indirect then double indirect zones. Keep
track of progress within inode

Include

To use this procedure, include the library:

include minixfs

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f27j53_sd_card_minix_read.jal

-- Title: Minix FS sample showing how to read file's content
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read file's content. This requires
-- to open a file, read some content, possibly seek (move) to a specific
-- location and, don't forget, close the file.
-- .
-- MinixFS uses some kind of file descriptor to access file, in order to know
-- current state, etc... Note there's only one file description available in
-- current MinixFS implementation.
-- .
-- This sample is based on a data set, available here:
-- http://code.google.com/p/jaluino/source/browse/trunk/tests/minix_data.tar.bz2
-- You can use this dataset to perform tests. It contains several files with
-- very specifc size, I used it to develop and test MinixFS, and this is a great
-- source of data to understand how MinixFS works.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  enabled     -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs

-- We're going to read data from file2K. This files has the following
-- structure:
--    "START1111....111NEXT2222....2222END"
--     ^----------------^^---------------^
--          1 block           1 block
--
-- Note the link between the two blocks: "NE" then "XT"

-- Here we go !

-- define which file we're going to open
-- minix_open() will expect a string of 30 chars
-- "file2K" has 6 chars, so either ignore the warning claiming
-- "fewer initializers than expected", or fill in extra space chars
-- Finally, because a filename can fit anywhere between 1 or 30 chars
-- we need to use NULL-terminated string in order MinixFS to know
-- where the filename fits
-- PS: I don't like warnings so I added extra padding chars
const byte myfile[MINIX_MAX_FILENANE_LEN] = "file2K\0                       "
minix_open(myfile,MINIX_MODE_READ)

-- let's read the "START"
for 4 loop
   serial_hw_data = minix_read()
end loop
-- can you see "START" on your serial link ?
print_crlf(serial_hw_data)

-- now let've move near the end of the first block
minix_seek(1022)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should give "NE"
serial_hw_data = minix_read() -- we moved to the 2nd block !
serial_hw_data = minix_read()
-- should give "XT"
print_crlf(serial_hw_data)

-- Now let's move to the end of file
minix_seek(2045)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should print "END"
print_crlf(serial_hw_data)

-- where are we within the file ?
-- well, what's the size ?
-- let's access some information from File Descriptor
-- and inode records
const byte sz[] = "Size: "
print_string(serial_hw_data,sz)
print_dword_dec(serial_hw_data,minix_filefd.inode.filesize)
print_crlf(serial_hw_data)
-- and how much did we read ?
const byte rd[] = "Read: "
print_string(serial_hw_data,rd)
print_dword_dec(serial_hw_data,minix_filefd.read)
print_crlf(serial_hw_data)
-- alright, this means there's nothing to read further ?
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- => print nothing !
-- ok, don't forget to close file. If you access another file
-- without closing previous, you may just get stuck ("crash")
minix_close()

print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

-- Sounds like we have everything to implement "cat" command :)
-- note: minix v2have max filename lenght = 30
procedure my_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is
   minix_open(filename,MINIX_MODE_READ)
   while minix_filefd.read != minix_filefd.inode.filesize loop
      serial_hw_data = minix_read()
   end loop
   minix_close()
end procedure
-- (you can find this procedure in minixfs_cmd.jal)

my_cat(myfile)
print_crlf(serial_hw_data)

-- enough, let's do nothing...
forever loop
end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_seek - JALlib Procedures Help

minix_seek JALLIB PROCEDURE

Signature

procedure minix_seek(dword in bytenum) is

Description

move to byte bytenum within a file
Notes: assuming file was just opened, no data read
bytenum must be <= filesize, if greater, expect troubles

Include

To use this procedure, include the library:

include minixfs

Parameters

  • bytenum - dword in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_read.jal

-- Title: Minix FS sample showing how to read file's content
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read file's content. This requires
-- to open a file, read some content, possibly seek (move) to a specific
-- location and, don't forget, close the file.
-- .
-- MinixFS uses some kind of file descriptor to access file, in order to know
-- current state, etc... Note there's only one file description available in
-- current MinixFS implementation.
-- .
-- This sample is based on a data set, available here:
-- http://code.google.com/p/jaluino/source/browse/trunk/tests/minix_data.tar.bz2
-- You can use this dataset to perform tests. It contains several files with
-- very specifc size, I used it to develop and test MinixFS, and this is a great
-- source of data to understand how MinixFS works.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  enabled     -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs

-- We're going to read data from file2K. This files has the following
-- structure:
--    "START1111....111NEXT2222....2222END"
--     ^----------------^^---------------^
--          1 block           1 block
--
-- Note the link between the two blocks: "NE" then "XT"

-- Here we go !

-- define which file we're going to open
-- minix_open() will expect a string of 30 chars
-- "file2K" has 6 chars, so either ignore the warning claiming
-- "fewer initializers than expected", or fill in extra space chars
-- Finally, because a filename can fit anywhere between 1 or 30 chars
-- we need to use NULL-terminated string in order MinixFS to know
-- where the filename fits
-- PS: I don't like warnings so I added extra padding chars
const byte myfile[MINIX_MAX_FILENANE_LEN] = "file2K\0                       "
minix_open(myfile,MINIX_MODE_READ)

-- let's read the "START"
for 4 loop
   serial_hw_data = minix_read()
end loop
-- can you see "START" on your serial link ?
print_crlf(serial_hw_data)

-- now let've move near the end of the first block
minix_seek(1022)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should give "NE"
serial_hw_data = minix_read() -- we moved to the 2nd block !
serial_hw_data = minix_read()
-- should give "XT"
print_crlf(serial_hw_data)

-- Now let's move to the end of file
minix_seek(2045)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should print "END"
print_crlf(serial_hw_data)

-- where are we within the file ?
-- well, what's the size ?
-- let's access some information from File Descriptor
-- and inode records
const byte sz[] = "Size: "
print_string(serial_hw_data,sz)
print_dword_dec(serial_hw_data,minix_filefd.inode.filesize)
print_crlf(serial_hw_data)
-- and how much did we read ?
const byte rd[] = "Read: "
print_string(serial_hw_data,rd)
print_dword_dec(serial_hw_data,minix_filefd.read)
print_crlf(serial_hw_data)
-- alright, this means there's nothing to read further ?
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- => print nothing !
-- ok, don't forget to close file. If you access another file
-- without closing previous, you may just get stuck ("crash")
minix_close()

print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

-- Sounds like we have everything to implement "cat" command :)
-- note: minix v2have max filename lenght = 30
procedure my_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is
   minix_open(filename,MINIX_MODE_READ)
   while minix_filefd.read != minix_filefd.inode.filesize loop
      serial_hw_data = minix_read()
   end loop
   minix_close()
end procedure
-- (you can find this procedure in minixfs_cmd.jal)

my_cat(myfile)
print_crlf(serial_hw_data)

-- enough, let's do nothing...
forever loop
end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_write - JALlib Procedures Help

minix_write JALLIB PROCEDURE

Signature

procedure minix_write(byte in data) is

Description

write a byte to current opened file descriptor

Include

To use this procedure, include the library:

include minixfs

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_read.jal

-- Title: Minix FS sample showing how to read file's content
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read file's content. This requires
-- to open a file, read some content, possibly seek (move) to a specific
-- location and, don't forget, close the file.
-- .
-- MinixFS uses some kind of file descriptor to access file, in order to know
-- current state, etc... Note there's only one file description available in
-- current MinixFS implementation.
-- .
-- This sample is based on a data set, available here:
-- http://code.google.com/p/jaluino/source/browse/trunk/tests/minix_data.tar.bz2
-- You can use this dataset to perform tests. It contains several files with
-- very specifc size, I used it to develop and test MinixFS, and this is a great
-- source of data to understand how MinixFS works.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  enabled     -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs

-- We're going to read data from file2K. This files has the following
-- structure:
--    "START1111....111NEXT2222....2222END"
--     ^----------------^^---------------^
--          1 block           1 block
--
-- Note the link between the two blocks: "NE" then "XT"

-- Here we go !

-- define which file we're going to open
-- minix_open() will expect a string of 30 chars
-- "file2K" has 6 chars, so either ignore the warning claiming
-- "fewer initializers than expected", or fill in extra space chars
-- Finally, because a filename can fit anywhere between 1 or 30 chars
-- we need to use NULL-terminated string in order MinixFS to know
-- where the filename fits
-- PS: I don't like warnings so I added extra padding chars
const byte myfile[MINIX_MAX_FILENANE_LEN] = "file2K\0                       "
minix_open(myfile,MINIX_MODE_READ)

-- let's read the "START"
for 4 loop
   serial_hw_data = minix_read()
end loop
-- can you see "START" on your serial link ?
print_crlf(serial_hw_data)

-- now let've move near the end of the first block
minix_seek(1022)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should give "NE"
serial_hw_data = minix_read() -- we moved to the 2nd block !
serial_hw_data = minix_read()
-- should give "XT"
print_crlf(serial_hw_data)

-- Now let's move to the end of file
minix_seek(2045)
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- should print "END"
print_crlf(serial_hw_data)

-- where are we within the file ?
-- well, what's the size ?
-- let's access some information from File Descriptor
-- and inode records
const byte sz[] = "Size: "
print_string(serial_hw_data,sz)
print_dword_dec(serial_hw_data,minix_filefd.inode.filesize)
print_crlf(serial_hw_data)
-- and how much did we read ?
const byte rd[] = "Read: "
print_string(serial_hw_data,rd)
print_dword_dec(serial_hw_data,minix_filefd.read)
print_crlf(serial_hw_data)
-- alright, this means there's nothing to read further ?
serial_hw_data = minix_read()
serial_hw_data = minix_read()
serial_hw_data = minix_read()
-- => print nothing !
-- ok, don't forget to close file. If you access another file
-- without closing previous, you may just get stuck ("crash")
minix_close()

print_crlf(serial_hw_data)
print_crlf(serial_hw_data)

-- Sounds like we have everything to implement "cat" command :)
-- note: minix v2have max filename lenght = 30
procedure my_cat(byte in filename[MINIX_MAX_FILENANE_LEN]) is
   minix_open(filename,MINIX_MODE_READ)
   while minix_filefd.read != minix_filefd.inode.filesize loop
      serial_hw_data = minix_read()
   end loop
   minix_close()
end procedure
-- (you can find this procedure in minixfs_cmd.jal)

my_cat(myfile)
print_crlf(serial_hw_data)

-- enough, let's do nothing...
forever loop
end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minix_zone_alloc - JALlib Procedures Help

minix_zone_alloc JALLIB FUNCTION

Signature

function minix_zone_alloc() return dword is

Description

Walk accross zone bitmap, searching for a free zone number (identified by 0s)
and return available zone number.
/!\ zone bitmap and file's content obviously aren't located the same. This means when
allocating, we're moving in a different place (zone bitmap) than we previously were
while writing into the file. It's the caller's responsability to move the correct location
once allocation is done. Yes, that's right: it's dirty, as zone_alloc() won't let the system
in its previous state. ("why ?" you may ask... because it's simpler like that, and anyway,
this procedure is somewhat internal, so it shouldn't be a problem in the end).

Include

To use this procedure, include the library:

include minixfs

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: minixfs.jal


minixfs.jal - JALLIB Library Documentation

minixfs.jal JALLIB LIBRARY

Title

Minix v2 filesystem implementation

Author

Sebastien Lelong, Copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Minix v2 implementation
Partitions aren't supported, so you have to create a filesystem on the whole
available memory. Typically, instead of "mkfs.minix -v /dev/sdX1", you'll
have to "mkfs.minix -v /dev/sdX" (and remove sdX1 partition with fdisk)
Some useful commands:
- fsck.minix -f -v -s /dev/sdX
will print Super-Block and some other information about files, dirs, state
- hexdump -C /dev/sdX
will dump Minix FS content (only changing lines)
- hexdump -v -C /dev/sdX
will do the same, but dump all lines, even if identical
.
In order to test your setup, you can untar minix_data.tar.bz2 available at:
...
This archive contains directories and files of different size, used to test
data zone and helping to understand how Minix filesystem is designed.
1. prepare your device, no partition (replace /dev/sdX with appropriate device):
mkfs.minix -v /dev/sdX
mount /dev/sdX /mnt/tmp
2. untar test data:
cd /mnt/tmp && tar xjfv path/to/minix_data.tar.bz2
cd && umount /mnt/tmp
3. check content:
fsck.minix -f -v -s /dev/sdX
should report something like (1GB SD-card used here):
.
Forcing filesystem check on /dev/sdX.
65535 inodes
992000 blocks
Firstdatazone=4227 (4227)
Zonesize=1024
Maxsize=2147483647
Filesystem state=1
namelen=30
.
20 inodes used (0%)
70858 zones used (7%)
.
16 regu
16 regular files
2 directories
0 character device files
0 block device files
1 links
2 symbolic links
------
21 files
.
Vocabulary: these are the terms I'm using in this code, may be wrong...
* storage: this is the underlying storage layer. Link between MinixFS and storage is done
by creating aliases to some spefici proc/funcs. Typically, storage is sd_card.jal
library. It could also be hard-disk too.
* sector: this is a unit in underlying storage (eg. for SD cards, 512 bytes)
* block: this is a unit in minixfs (typically 1024 bytes, that is, 2 * sector's size with SD cards)
* zone: same as a block in case of Minix v2
* inode: well, that's an inode, a kind of meta description of a file
* file descriptor: a structure composed with an inode and several information to track how file was
opened and where we are within a file (well, again, that's a file descriptor)

Notes

* I developped this lib and tested it with sd_card storage. It should be possible to use other
* storages though not tested nor even tried.
* to developpers: this piece of code is tricky... If you plan to modify this lib, take huge care
at variables initialization, there are special values I used, mostly to rollover
to 0 when first accessed. It could have been simpler but would have used more
variables and thus more resources. There are many counters which, when reaching
a specific value, trigger actions (like flushing data, going to next zone, allocate
a new zone, etc...). Just don't assume it'll work just because you added a small
little line, because everything is quite tied together and you could be victim
of an (un)expected butterfly effect :) I myself broke features many times with
supposedly minor changes, hurting my brain a lot. Being polite...
TODO:
* update atime/mtime/ctime while reading & writing
* update mode bits while saving inode
* rename open_block_byte
* support for file creation
* support for file deletion

Constants and Variables

MINIX_SUPER_MAGIC - const word = 0x137F -- original minix fs
original minix fs
MINIX_SUPER_MAGIC2 - const word = 0x138F -- minix fs, 30 char names
minix fs, 30 char names
MINIX2_SUPER_MAGIC - const word = 0x2468 -- minix V2 fs
minix V2 fs
MINIX2_SUPER_MAGIC2 - const word = 0x2478 -- minix V2 fs, 30 char names
minix V2 fs, 30 char names
MINIX3_SUPER_MAGIC - const word = 0x4D5A -- minix V3 fs
minix V3 fs
MINIX_BYTES_PER_BLOCK - const word = 0x400 -- 1KB per block
1KB per block
MINIX_BYTES_PER_INODE - const word = 0x40 -- 64B per inode
64B per inode
MINIX_BOOT_BLOCK_ADDRESS - const word = 0x00
MINIX_SUPER_BLOCK_ADDRESS - const word = MINIX_BOOT_BLOCK_ADDRESS + MINIX_BYTES_PER_BLOCK
MINIX_MAX_FILENANE_LEN - const byte = 30
MINIX_MAX_DIRECT_ZONE_IDX - const byte = 6
MINIX_MAX_INDIRECT_ZONE_IDX - const word = 0x03FC -- 0x400 - 4 == one block - one location
0x400 - 4 == one block - one location
MINIX_MAX_DOUBLE_DIRECT_ZONE_IDX - const word = 0x03FC -- 0x400 - 4 == one block - one location
0x400 - 4 == one block - one location
MINIX_NUM_DIRECT_ZONES - const byte = 7
MINIX_NUM_INDIRECT_ZONES - const dword = 256
MINIX_NUM_DOUBLE_INDIRECT_ZONES - const dword = 65536
MINIX_MAX_DIRECT_ZONE_SIZE - const dword = MINIX_NUM_DIRECT_ZONES * MINIX_BYTES_PER_BLOCK
MINIX_MAX_INDIRECT_ZONE_SIZE - const dword = (MINIX_NUM_INDIRECT_ZONES * MINIX_BYTES_PER_BLOCK) + MINIX_MAX_DIRECT_ZONE_SIZE
MINIX_ZONE_NONE - const byte = 0b_0000
MINIX_ZONE_DIRECT - const byte = 0b_0001
MINIX_ZONE_INDIRECT - const byte = 0b_0010
MINIX_ZONE_DOUBLE_INDIRECT - const byte = 0b_0100
MINIX_ZONE_TRIPLE_INDIRECT - const byte = 0b_1000
MINIX_NUM_ZONE_BITS_PER_BLOCK - const dword = MINIX_BYTES_PER_BLOCK * 8
MINIX_MODE_READ - const byte = 0b001
MINIX_MODE_WRITE - const byte = 0b010
MINIX_MODE_APPEND - const byte = 0b100 -- write implied
write implied
MINIX_ERR_NONE - const byte = 0b_0000_0000
MINIX_ERR_BAD_MAGIC_NUMBER - const byte = 0b_0000_0001 -- magic number unsupported
magic number unsupported
MINIX_ERR_BAD_ZONE_LOCATION - const byte = 0b_0000_0010 -- something is wrong about declared and computed data location
something is wrong about declared and computed data location
MINIX_ERR_NOT_DIRECTORY - const byte = 0b_0000_0100 -- try to act on a directory, but inode isn't a directory
try to act on a directory, but inode isn't a directory
MINIX_ERR_NO_SUCH_FILE - const byte = 0b_0000_1000 -- try to access invalid/unexisting filename or inode
try to access invalid/unexisting filename or inode
MINIX_ERR_END_OF_FILE - const byte = 0b_0001_0000 -- reached EOF
reached EOF
MINIX_ERR_BAD_ADDRESS - const byte = 0b_0010_0000 -- bad block address
bad block address
MINIX_INODE_ROOT_ID - const word = 1
minix_curzone - var dword
minix_sector_progress - var word = 0 -- track progress while accessing underlying storage sector
track progress while accessing underlying storage sector
minix_storage_address - var dword = 0 -- track underlying storage address
track underlying storage address
minix_sb - var minix_superblock
minix_filefd - var minix_fd
minix_cwd - var word

Routines

  • minix_cd - Procedure
  • minix_cdi - Procedure
  • minix_close - Procedure
  • minix_find_in_cwd - Function returns word
  • minix_flush - Procedure
  • minix_init - Procedure
  • minix_last_error'get - Function returns byte
  • minix_last_error'put - Procedure
  • minix_load_inode - Procedure
  • minix_next_entry'get - Function returns minix_dir_entry
  • minix_next_zone - Procedure
  • minix_open - Procedure
  • minix_open_block - Procedure
  • minix_open_block_byte - Procedure
  • minix_openi - Procedure
  • minix_read - Function returns byte
  • minix_read_super_block - Procedure
  • minix_save_inode - Procedure
  • minix_seek - Procedure
  • minix_storage_flush - Procedure
  • minix_storage_read_byte - Function returns byte
  • minix_storage_write_byte - Procedure
  • minix_write - Procedure
  • minix_zone_alloc - Function returns dword


minixfs_cmd.jal - JALLIB Library Documentation

minixfs_cmd.jal JALLIB LIBRARY

Title

Minix v2 filesystem, usefull yet optional commands

Author

Sebastien Lelong, Copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

As a (optional) bonus, this library provides useful commands while
dealing with MinixFS, like printing file's content, print super block, etc...
Some require prior definition of "minix_print_carrier" pseudo-var definition,
used to actually display data (typically serial_hw_data, usb_serial_data, etc...)
If not defined, others can still be used.
Careful, using these commands can cost a lot of resources...

Routines

  • minix_cat - Procedure
  • minix_cati - Procedure
  • minix_dev_cat - Procedure
  • minix_dev_cati - Procedure
  • minix_dev_print_error - Procedure
  • minix_dev_print_inode - Procedure
  • minix_dev_print_super_block - Procedure
  • minix_ls - Procedure
  • minix_lsi - Procedure
  • minix_print_dir_entry - Procedure


mp3_decoder_sta015.jal - JALLIB Library Documentation

mp3_decoder_sta015.jal JALLIB LIBRARY

Title

sta015/sta013 mp3 decoder sample

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

example usage of the sta015 mp3 decoder. plays .mp3 files from
a fat32 formatted sd card or hard disk

Sources

http://www.st.com/stonline/books/pdf/docs/7042.pdf
http://www.pjrc.com/mp3/sta013.html
notes:
vs1053b is a better mp3 decoder device
Oscillator values can be 20mhz, 10mhz, 14.31818 mhz or 14.7456 mhz.
Base and treble max can not go above sta015_attenuation value. If you want base and
treble control, you must raise STA015_DEFAULT_ATTENUATION
you may do things while the song is playing while sta015_data_request = high
sta015 works in SPI mode 0,1 .
Send mp3 data as fast as possible for high bitrate mp3

useful variables --

send one of the following constants to the sta015_write_command procedure

Constants and Variables

STA015_RESET - const byte = 100 -- Reset the sta015 device
Reset the sta015 device
STA015_START_PLAY - const byte = 101 -- Tell the device to start playing. You need to send data after
Tell the device to start playing. You need to send data after
STA015_STOP_PLAY - const byte = 102 -- Tell device to stop playing. Or just stop sending data
Tell device to stop playing. Or just stop sending data
STA015_MUTE - const byte = 103 -- Mute (turn off volume but continue playing)
Mute (turn off volume but continue playing)
STA015_NO_MUTE - const byte = 104 -- Turn off Mute (restore volume)
Turn off Mute (restore volume)
STA015_VOLUME_DOWN - const byte = 105 -- Turn down the volume (more attenuation)
Turn down the volume (more attenuation)
STA015_VOLUME_UP - const byte = 106 -- Turn up the volume (less attenuation)
Turn up the volume (less attenuation)
STA015_BASE_DOWN - const byte = 107 -- Turn down base (low frequency sounds)
Turn down base (low frequency sounds)
STA015_BASE_UP - const byte = 108 -- Turn up base (low frequency sounds)
Turn up base (low frequency sounds)
STA015_TREBLE_DOWN - const byte = 109 -- Turn down treble (high frequency sounds)
Turn down treble (high frequency sounds)
STA015_TREBLE_UP - const byte = 110 -- Turn up the treble (high frequency sounds)
Turn up the treble (high frequency sounds)
STA015_RIGHT_DOWN - const byte = 111 -- Turn down the right speaker volume
Turn down the right speaker volume
STA015_RIGHT_UP - const byte = 112 -- Turn up the right speaker volume
Turn up the right speaker volume
STA015_LEFT_DOWN - const byte = 113 -- Turn down the left speaker volume
Turn down the left speaker volume
STA015_LEFT_UP - const byte = 114 -- Turn up the left speaker volume
Turn up the left speaker volume
STA015_READ_INFO - const byte = 115 -- Get mp3 bitrate and mode(mono/stereo) with sta015_read_mp3_info() command
Get mp3 bitrate and mode(mono/stereo) with sta015_read_mp3_info() command
STA015_STEREO - const byte = 0 -- stereo
stereo
STA015_JOINT_STEREO - const byte = 1 -- joint stereo (intensity_stereo and/or ms_stereo)
joint stereo (intensity_stereo and/or ms_stereo)
STA015_DUAL_CHANNEL - const byte = 2 -- dual_channel
dual_channel
STA015_SINGLE_CHANNEL - const byte = 3 -- single_channel (mono)
single_channel (mono)
sta015_bitrate - var word
STA015_OSC_10 - const byte = 0 -- 10 mhz crystal
10 mhz crystal
STA015_OSC_20 - const byte = 1 -- 20 mhz crystal
20 mhz crystal
STA015_OSC_14_31818 - const byte = 2 -- 14.31818 mhz crystal
14.31818 mhz crystal
STA015_OSC_14_7456 - const byte = 3 -- 14.7456 mhz crystal
14.7456 mhz crystal
sta015_attenuation - var byte = STA015_DEFAULT_ATTENUATION -- current attenuation / volume
current attenuation / volume
sta015_base - var sbyte = 0 -- current base volume
current base volume
sta015_treble - var sbyte = 0 -- current treble volume
current treble volume
sta015_left - var byte = 0 -- current left speaker volume
current left speaker volume
sta015_right - var byte = 0 -- current right speaker volume
current right speaker volume

Routines

  • sta015_init - Procedure
  • sta015_read_mp3_info - Procedure
  • sta015_read_register - Procedure
  • sta015_send - Procedure
  • sta015_send_volume - Procedure
  • sta015_write_command - Procedure
  • sta015_write_register - Procedure


mp3_decoder_vs1053b.jal - JALLIB Library Documentation

mp3_decoder_vs1053b.jal JALLIB LIBRARY

Title

vs1053b mp3 decoder sample

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

example usage of the vs1053 mp3 decoder. plays .mp3 files from
a fat32 formatted sd card. Full control of play speed, volume,
right/left speaker, bass, treble, mute. Also plays
Ogg Vorbis/AAC/WMA/MIDI

Notes

vs1053 uses SPI mode 0,0
must use 12.288mhz crystal for vs1053b

Sources

VLSI Solutions Datasheet - www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf

if initialization was ok, this will change to TRUE

Constants and Variables

vs_init_ok - var bit = FALSE
VS_REG_MODE - const byte = 0x00
VS_REG_STATUS - const byte = 0x01
VS_REG_BASS - const byte = 0x02
VS_REG_CLOCKF - const byte = 0x03
VS_REG_DECODE_TIME - const byte = 0x04
VS_REG_AUDATA - const byte = 0x05
VS_REG_WRAM - const byte = 0x06
VS_REG_WRAMADDR - const byte = 0x07
VS_REG_HDAT0 - const byte = 0x08
VS_REG_HDAT1 - const byte = 0x09
VS_REG_AIADDR - const byte = 0x0A
VS_REG_VOL - const byte = 0x0B
VS_REG_AICTRL0 - const byte = 0x0C
VS_REG_AICTRL1 - const byte = 0x0D
VS_REG_AICTRL2 - const byte = 0x0E
VS_REG_AICTRL3 - const byte = 0x0F
vs_current_bass - var byte = 0
vs_current_treble - var sbyte = 0
vs_port_gpio_data - var byte = 0
vs_port_gpio_direction_data - var byte = 0

Routines

  • _vs_send_mp3 - Procedure
  • _vs_set_bass_treble_set - Procedure
  • _vs_volume_set - Procedure
  • vs_bass'get - Function returns byte
  • vs_bass'put - Procedure
  • vs_file_info - Procedure
  • vs_init - Procedure
  • vs_line_in_mode - Procedure
  • vs_microphone_mode - Procedure
  • vs_mute'get - Function returns bit
  • vs_mute'put - Procedure
  • vs_patch_vs1053b - Procedure
  • vs_pin_gpio0'get - Function returns bit
  • vs_pin_gpio0'put - Procedure
  • vs_pin_gpio0_direction'get - Function returns bit
  • vs_pin_gpio0_direction'put - Procedure
  • vs_pin_gpio1'get - Function returns bit
  • vs_pin_gpio1'put - Procedure
  • vs_pin_gpio1_direction'get - Function returns bit
  • vs_pin_gpio1_direction'put - Procedure
  • vs_pin_gpio2'get - Function returns bit
  • vs_pin_gpio2'put - Procedure
  • vs_pin_gpio2_direction'get - Function returns bit
  • vs_pin_gpio2_direction'put - Procedure
  • vs_pin_gpio3'get - Function returns bit
  • vs_pin_gpio3'put - Procedure
  • vs_pin_gpio3_direction'get - Function returns bit
  • vs_pin_gpio3_direction'put - Procedure
  • vs_pin_gpio4'get - Function returns bit
  • vs_pin_gpio4'put - Procedure
  • vs_pin_gpio4_direction'get - Function returns bit
  • vs_pin_gpio4_direction'put - Procedure
  • vs_pin_gpio5'get - Function returns bit
  • vs_pin_gpio5'put - Procedure
  • vs_pin_gpio5_direction'get - Function returns bit
  • vs_pin_gpio5_direction'put - Procedure
  • vs_pin_gpio6'get - Function returns bit
  • vs_pin_gpio6'put - Procedure
  • vs_pin_gpio6_direction'get - Function returns bit
  • vs_pin_gpio6_direction'put - Procedure
  • vs_pin_gpio7'get - Function returns bit
  • vs_pin_gpio7'put - Procedure
  • vs_pin_gpio7_direction'get - Function returns bit
  • vs_pin_gpio7_direction'put - Procedure
  • vs_play - Procedure
  • vs_play_mode - Procedure
  • vs_play_speed'get - Function returns byte
  • vs_play_speed'put - Procedure
  • vs_port_gpio'get - Function returns byte
  • vs_port_gpio'put - Procedure
  • vs_port_gpio_direction'get - Function returns byte
  • vs_port_gpio_direction'put - Procedure
  • vs_read_ram - Procedure
  • vs_reg_read_to_serial - Procedure
  • vs_register_read - Procedure
  • vs_register_write - Procedure
  • vs_soft_reset - Procedure
  • vs_stop - Procedure
  • vs_treble'get - Function returns sbyte
  • vs_treble'put - Procedure
  • vs_volume'get - Function returns byte
  • vs_volume'put - Procedure
  • vs_volume_left'get - Function returns sbyte
  • vs_volume_left'put - Procedure
  • vs_volume_right'get - Function returns sbyte
  • vs_volume_right'put - Procedure


Multiplication, Division, Modulus Division - JAL Language Syntax Reference

Multiplication, Division, Modulus Division JALV2 SYNTAX

Syntax

n = x / 10 r = x % 10

Description

Multiplication, Division, and Modulus Division are internal mainly because there is no way to predetermine the size of the operands. Note that unlike the other operators which are done inline, these are function calls and require one stack entry when used! A second reason for having these built in is the optimizer -- when a multiplication or division by 1 is done, the operation is ignored. When a multiplication or division by a power of two is done, the resulting code is performed using shifts instead. For both of these operations, the code generated will be that required for the largest operands unless -fastmath is passed to the compiler. For example, if the operation occurs only between two BYTEs, the 8-bit routine will be generated. If it occurs between BYTEs and WORDs, the 16-bit routine will be generated. If -fastmath is used, a different function will be generated for each argument type. The compiler keeps track of the last operation, so if you find yourself needing both the division result and the remainder of, a certain operation, make sure to put the assignments close together, thus saving a function call: will only result in one call to the division -- the assignment to r will be a simple assignment.

Generated by JAL Syntax Documentation System | Source: DITA


Named Constants - JAL Language Syntax Reference

Named Constants JALV2 SYNTAX

Generated by JAL Syntax Documentation System | Source: DITA


nec_rc_decoder.jal - JALLIB Library Documentation

nec_rc_decoder.jal JALLIB LIBRARY

Title

NEC Infra Red Remote Control Decoder Library.

Author

Rob Jansen, Copyright (c) 2023..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for decoding NEC Remote Control messages. The library
can be configured to use either the external interrupt or an
IOC interrupt to decode the Remote Control Messages.
The default is using an external interupt. In order to switch
to using an IOC interrupt the user must initialize the IOC
to be active on both the rising and falling edge and must
define the following alias (example for IOC on pin A2):
alias nec_rc_decoder_ioc_flag is IOCAF_IOCAF2
The library uses Timer 1 to measure the the bit times
The user must initialize Timer 1. Bit times are based on 1 us.
If Timer 1 does not run at 1 MHz then the user has to define
the dword constant NEC_RC_SCALING, where a value of 100 equals
Timer 1 running at 1 MHz. When Timer 1 runs at 1.25 MHz the
dword constant NEC_RC_SCALING must equal 125. Same when
Timer 1 runs at 0.75 MHz NEC_RC_SCALING must equal 75.
The standard NEC protocol (default) or the extended
NEC protocol can be selected for decoding.

Notes

The 38 kHz Infra Red receiver (active low) must be connected
to the external interrupt pin or the used IOC pin.

Sources

Documentation on the NEC protocol:
https://www.renesas.com/us/en/document/apn/1184-remote-control-ir-receiver-decoder

----------------------------------------------------------------------------
-------------------------- Public API --------------------------------------
----------------------------------------------------------------------------

----------------------------------------------------------------------------
Initialize the NEC Remote Control Decoder. This will initialize timer 1
and will enable the required interrupts. The Remote Control Decoder is set
to support the standard NEC protocol.
----------------------------------------------------------------------------

Constants and Variables

NEC_RC_SCALING - const dword = 100

Routines

  • _nec_rc_get_timer1_value - Function returns word
  • _nec_rc_handle_interrupt_flag - Function returns bit
  • _nec_rc_interrupt - Procedure
  • _nec_rc_reset_decoder - Procedure
  • _nec_rc_timer1_interrupt - Procedure
  • _nec_rc_timer1_reset - Procedure
  • nec_rc_decoder_init - Procedure
  • nec_rc_get_data_extended - Procedure
  • nec_rc_get_data_standard - Procedure
  • nec_rc_message_received - Function returns bit
  • nec_rc_repeat_received - Function returns bit
  • nec_rc_set_protocol_extended - Procedure
  • nec_rc_set_protocol_standard - Procedure


nec_rc_decoder_init - JALlib Procedures Help

nec_rc_decoder_init JALLIB PROCEDURE

Signature

procedure nec_rc_decoder_init() is

Description

Initialize the NEC Remote Control Decoder. This will initialize timer 1
and will enable the required interrupts. The Remote Control Decoder is set
to support the standard NEC protocol.

Include

To use this procedure, include the library:

include nec_rc_decoder

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nec_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the NEC Remote Control Decoder using USART
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows NEC Remote Control commands commands via
--              the serial interface using the external interrupt of the PIC.
--              An example is also included when using a local constant
--              IOC_VERSION to use the IOC instead of the external interrupt.
--
-- Notes:       The 38 kHz Infra Red receiver (active low) must be connected
--              to the external interrupt pin or the used IOC pin.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Set up the serial interface.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print

-- Settings for the NEC Remote Control Decoder. The decoder uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a MHz clock cannot be obtained the user must use NEC_RC_SCALING.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.
-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the Remote Control decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias nec_rc_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias nec_rc_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias nec_rc_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Now we can include the library.
include nec_rc_decoder
nec_rc_decoder_init()

-- There is also an extended NEC Remote Control Protocol. In this
-- sample program you can switch to this by defining the following
-- local constant:
-- const USE_NEC_EXTENDED_PROTOCOL = TRUE
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   nec_rc_set_protocol_extended()
end if

-- Variables.
var word repeat_counter = 0
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   var word address
else
   var byte address
end if
var byte command

-- Main program starts here.
print_crlf(serial)
print_string(serial,"NEC REMOTE CONTROL ")
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   print_string(serial,"EXTENDED DECODER")
else
   print_string(serial,"STANDARD DECODER")
end if
print_crlf(serial)

forever  loop

   if nec_rc_message_received() then
      -- Reset repeat counter since new message.
      repeat_counter = 0
      -- Print the (extended) address
      print_string(serial, "ADDRESS: ")
      if defined(USE_NEC_EXTENDED_PROTOCOL) then
         nec_rc_get_data_extended(address, command)
         print_word_dec(serial, address)
      else
         nec_rc_get_data_standard(address, command)
         print_byte_dec(serial, address)
      end if
      print_crlf(serial)
      -- Print the command.
      print_string(serial, "COMMAND: ")
      print_byte_dec(serial, command)
      print_crlf(serial)
   elsif nec_rc_repeat_received then
      -- Only a repeat message, increment repeat counter.
      repeat_counter = repeat_counter + 1
      print_string(serial, "REPEAT: ")
      print_word_dec(serial, repeat_counter)
      print_crlf(serial)
   end if

end loop

Generated by JALlib CHM Help System | Source: nec_rc_decoder.jal


nec_rc_get_data_extended - JALlib Procedures Help

nec_rc_get_data_extended JALLIB PROCEDURE

Signature

procedure nec_rc_get_data_extended(word out address, byte out command) is

Description

Return the last received Remote Control data using the extended protocol.
When called, the message received flag is cleared.

Include

To use this procedure, include the library:

include nec_rc_decoder

Parameters

  • address - word out
  • command - byte out

Return Value

None

Example

From sample file: 16f1825_nec_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the NEC Remote Control Decoder using USART
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows NEC Remote Control commands commands via
--              the serial interface using the external interrupt of the PIC.
--              An example is also included when using a local constant
--              IOC_VERSION to use the IOC instead of the external interrupt.
--
-- Notes:       The 38 kHz Infra Red receiver (active low) must be connected
--              to the external interrupt pin or the used IOC pin.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Set up the serial interface.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print

-- Settings for the NEC Remote Control Decoder. The decoder uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a MHz clock cannot be obtained the user must use NEC_RC_SCALING.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.
-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the Remote Control decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias nec_rc_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias nec_rc_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias nec_rc_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Now we can include the library.
include nec_rc_decoder
nec_rc_decoder_init()

-- There is also an extended NEC Remote Control Protocol. In this
-- sample program you can switch to this by defining the following
-- local constant:
-- const USE_NEC_EXTENDED_PROTOCOL = TRUE
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   nec_rc_set_protocol_extended()
end if

-- Variables.
var word repeat_counter = 0
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   var word address
else
   var byte address
end if
var byte command

-- Main program starts here.
print_crlf(serial)
print_string(serial,"NEC REMOTE CONTROL ")
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   print_string(serial,"EXTENDED DECODER")
else
   print_string(serial,"STANDARD DECODER")
end if
print_crlf(serial)

forever  loop

   if nec_rc_message_received() then
      -- Reset repeat counter since new message.
      repeat_counter = 0
      -- Print the (extended) address
      print_string(serial, "ADDRESS: ")
      if defined(USE_NEC_EXTENDED_PROTOCOL) then
         nec_rc_get_data_extended(address, command)
         print_word_dec(serial, address)
      else
         nec_rc_get_data_standard(address, command)
         print_byte_dec(serial, address)
      end if
      print_crlf(serial)
      -- Print the command.
      print_string(serial, "COMMAND: ")
      print_byte_dec(serial, command)
      print_crlf(serial)
   elsif nec_rc_repeat_received then
      -- Only a repeat message, increment repeat counter.
      repeat_counter = repeat_counter + 1
      print_string(serial, "REPEAT: ")
      print_word_dec(serial, repeat_counter)
      print_crlf(serial)
   end if

end loop

Generated by JALlib CHM Help System | Source: nec_rc_decoder.jal


nec_rc_get_data_standard - JALlib Procedures Help

nec_rc_get_data_standard JALLIB PROCEDURE

Signature

procedure nec_rc_get_data_standard(byte out address, byte out command) is

Description

Return the last received Remote Control data using the standard protocol.
When called, the message received flag is cleared.

Include

To use this procedure, include the library:

include nec_rc_decoder

Parameters

  • address - byte out
  • command - byte out

Return Value

None

Example

From sample file: 16f1825_nec_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the NEC Remote Control Decoder using USART
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows NEC Remote Control commands commands via
--              the serial interface using the external interrupt of the PIC.
--              An example is also included when using a local constant
--              IOC_VERSION to use the IOC instead of the external interrupt.
--
-- Notes:       The 38 kHz Infra Red receiver (active low) must be connected
--              to the external interrupt pin or the used IOC pin.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Set up the serial interface.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print

-- Settings for the NEC Remote Control Decoder. The decoder uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a MHz clock cannot be obtained the user must use NEC_RC_SCALING.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.
-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the Remote Control decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias nec_rc_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias nec_rc_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias nec_rc_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Now we can include the library.
include nec_rc_decoder
nec_rc_decoder_init()

-- There is also an extended NEC Remote Control Protocol. In this
-- sample program you can switch to this by defining the following
-- local constant:
-- const USE_NEC_EXTENDED_PROTOCOL = TRUE
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   nec_rc_set_protocol_extended()
end if

-- Variables.
var word repeat_counter = 0
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   var word address
else
   var byte address
end if
var byte command

-- Main program starts here.
print_crlf(serial)
print_string(serial,"NEC REMOTE CONTROL ")
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   print_string(serial,"EXTENDED DECODER")
else
   print_string(serial,"STANDARD DECODER")
end if
print_crlf(serial)

forever  loop

   if nec_rc_message_received() then
      -- Reset repeat counter since new message.
      repeat_counter = 0
      -- Print the (extended) address
      print_string(serial, "ADDRESS: ")
      if defined(USE_NEC_EXTENDED_PROTOCOL) then
         nec_rc_get_data_extended(address, command)
         print_word_dec(serial, address)
      else
         nec_rc_get_data_standard(address, command)
         print_byte_dec(serial, address)
      end if
      print_crlf(serial)
      -- Print the command.
      print_string(serial, "COMMAND: ")
      print_byte_dec(serial, command)
      print_crlf(serial)
   elsif nec_rc_repeat_received then
      -- Only a repeat message, increment repeat counter.
      repeat_counter = repeat_counter + 1
      print_string(serial, "REPEAT: ")
      print_word_dec(serial, repeat_counter)
      print_crlf(serial)
   end if

end loop

Generated by JALlib CHM Help System | Source: nec_rc_decoder.jal


nec_rc_message_received - JALlib Procedures Help

nec_rc_message_received JALLIB FUNCTION

Signature

function nec_rc_message_received() return bit is

Description

Returns TRUE when a valid Remote Control message was received.

Include

To use this procedure, include the library:

include nec_rc_decoder

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_nec_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the NEC Remote Control Decoder using USART
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows NEC Remote Control commands commands via
--              the serial interface using the external interrupt of the PIC.
--              An example is also included when using a local constant
--              IOC_VERSION to use the IOC instead of the external interrupt.
--
-- Notes:       The 38 kHz Infra Red receiver (active low) must be connected
--              to the external interrupt pin or the used IOC pin.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Set up the serial interface.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print

-- Settings for the NEC Remote Control Decoder. The decoder uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a MHz clock cannot be obtained the user must use NEC_RC_SCALING.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.
-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the Remote Control decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias nec_rc_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias nec_rc_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias nec_rc_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Now we can include the library.
include nec_rc_decoder
nec_rc_decoder_init()

-- There is also an extended NEC Remote Control Protocol. In this
-- sample program you can switch to this by defining the following
-- local constant:
-- const USE_NEC_EXTENDED_PROTOCOL = TRUE
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   nec_rc_set_protocol_extended()
end if

-- Variables.
var word repeat_counter = 0
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   var word address
else
   var byte address
end if
var byte command

-- Main program starts here.
print_crlf(serial)
print_string(serial,"NEC REMOTE CONTROL ")
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   print_string(serial,"EXTENDED DECODER")
else
   print_string(serial,"STANDARD DECODER")
end if
print_crlf(serial)

forever  loop

   if nec_rc_message_received() then
      -- Reset repeat counter since new message.
      repeat_counter = 0
      -- Print the (extended) address
      print_string(serial, "ADDRESS: ")
      if defined(USE_NEC_EXTENDED_PROTOCOL) then
         nec_rc_get_data_extended(address, command)
         print_word_dec(serial, address)
      else
         nec_rc_get_data_standard(address, command)
         print_byte_dec(serial, address)
      end if
      print_crlf(serial)
      -- Print the command.
      print_string(serial, "COMMAND: ")
      print_byte_dec(serial, command)
      print_crlf(serial)
   elsif nec_rc_repeat_received then
      -- Only a repeat message, increment repeat counter.
      repeat_counter = repeat_counter + 1
      print_string(serial, "REPEAT: ")
      print_word_dec(serial, repeat_counter)
      print_crlf(serial)
   end if

end loop

Generated by JALlib CHM Help System | Source: nec_rc_decoder.jal


nec_rc_set_protocol_extended - JALlib Procedures Help

nec_rc_set_protocol_extended JALLIB PROCEDURE

Signature

procedure nec_rc_set_protocol_extended() is

Description

Set the library to support the extended protocol.

Include

To use this procedure, include the library:

include nec_rc_decoder

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nec_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the NEC Remote Control Decoder using USART
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows NEC Remote Control commands commands via
--              the serial interface using the external interrupt of the PIC.
--              An example is also included when using a local constant
--              IOC_VERSION to use the IOC instead of the external interrupt.
--
-- Notes:       The 38 kHz Infra Red receiver (active low) must be connected
--              to the external interrupt pin or the used IOC pin.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(250_000)     -- Give the hardware some time to stabilize.

-- Set up the serial interface.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init
alias serial is serial_hw_data

include print

-- Settings for the NEC Remote Control Decoder. The decoder uses timer 1
-- which must run at 1 MHz. We use Fosc/4 and a prescaler of 1:8 to
-- get the 1 MHz timer 1 clock since the target clock is at 32 MHz.
-- Note: When a MHz clock cannot be obtained the user must use NEC_RC_SCALING.
T1CON_TMR1CS = 0b00 -- Clock source Fosc/4, gives 8 MHz.
T1CON_T1CKPS = 0b11 -- Prescaler 1:8, gives 1 MHz.
-- The following local constant is normally not required but is used here to
-- demonstrate the use of the IOC version. If you comment this constant
-- out the Remote Control decoder will use the external interrupt (default).
-- const IOC_VERSION = TRUE
if defined(IOC_VERSION) then
   -- Set the IOC interrupt on both edges and define the and aliases
   -- for the decoder routine. We use pin A5 in this example.
   IOCAP_IOCAP5 = TRUE -- Set ioc interrupt on positive edge
   IOCAN_IOCAN5 = TRUE -- Set ioc interrupt on negative edge.
   alias nec_rc_decoder_ioc_flag is IOCAF_IOCAF5
   -- Interupt pin using IOC.
   alias nec_rc_decoder_pin_direction is pin_a5_direction -- Pin 2 for 14 pin DIP
else
   -- Interupt pin using the external interrupt.
   alias nec_rc_decoder_pin_direction is pin_a2_direction -- Pin 11 for 14 pin DIP
end if
-- Now we can include the library.
include nec_rc_decoder
nec_rc_decoder_init()

-- There is also an extended NEC Remote Control Protocol. In this
-- sample program you can switch to this by defining the following
-- local constant:
-- const USE_NEC_EXTENDED_PROTOCOL = TRUE
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   nec_rc_set_protocol_extended()
end if

-- Variables.
var word repeat_counter = 0
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   var word address
else
   var byte address
end if
var byte command

-- Main program starts here.
print_crlf(serial)
print_string(serial,"NEC REMOTE CONTROL ")
if defined(USE_NEC_EXTENDED_PROTOCOL) then
   print_string(serial,"EXTENDED DECODER")
else
   print_string(serial,"STANDARD DECODER")
end if
print_crlf(serial)

forever  loop

   if nec_rc_message_received() then
      -- Reset repeat counter since new message.
      repeat_counter = 0
      -- Print the (extended) address
      print_string(serial, "ADDRESS: ")
      if defined(USE_NEC_EXTENDED_PROTOCOL) then
         nec_rc_get_data_extended(address, command)
         print_word_dec(serial, address)
      else
         nec_rc_get_data_standard(address, command)
         print_byte_dec(serial, address)
      end if
      print_crlf(serial)
      -- Print the command.
      print_string(serial, "COMMAND: ")
      print_byte_dec(serial, command)
      print_crlf(serial)
   elsif nec_rc_repeat_received then
      -- Only a repeat message, increment repeat counter.
      repeat_counter = repeat_counter + 1
      print_string(serial, "REPEAT: ")
      print_word_dec(serial, repeat_counter)
      print_crlf(serial)
   end if

end loop

Generated by JALlib CHM Help System | Source: nec_rc_decoder.jal


network_poll - JALlib Procedures Help

network_poll JALLIB PROCEDURE

Signature

procedure network_poll() is

Description

poll to see if there are any packets waiting for us

Include

To use this procedure, include the library:

include networking

Parameters

None

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: networking.jal


network_received_packet - JALlib Procedures Help

network_received_packet JALLIB PROCEDURE

Signature

procedure network_received_packet() is

Description

Reads a recieve packet. Verifies IP Header data such as IP
address and checksum (with ip_header.jal), then sends the
rest of the data to the correct procedure depending on packet type.

Include

To use this procedure, include the library:

include networking

Parameters

None

Return Value

None

Example

From sample file: 18f4620_network_slip_isr_ping_udp.jal

-- Title: Sample PING/UDP/ARP via SLIP BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample is for SLIP network communication using
--              a serial port. Sends/receives PING, UDP data packets.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://tools.ietf.org/html/rfc1055
--
-- Notes:
--
-- Notes:
-- This is being released as BETA.
--
-- Circuit MUST have all of the following:
-- Switches + pull up resistor connected to pin_d0, pin_d1.
-- led + resistor on pin_d2
-- serial sw: tx_pin is pin_B4, rx_pin is pin_B5
-- serial hw to slip connection
--
-- change "const WIN_XP_CONNECTION = TRUE" to false if you are not using
-- win XP "direct connect"
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()

alias debug_data is serial_sw_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF   -- network debug data
;debug_lvl_5 = ON
;debug_lvl_6 = ON

var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
--
button_direction = INPUT

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
--
button2_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup SLIP
const SLIP_MTU = 100                 -- Max bytes per packet (Max Transfer Unit)
const SLIP_USE_FOR_NETWORKING = TRUE -- use slip for networking
--
-- choose your interrupt routine. you may ignore this and create your own
-- isr or use polling method slip_poll()
const bit SLIP_USE_SERIAL_HW_ISR = TRUE -- TRUE = recieve data via serial hw interrupt
const SLIP_DO_CALLBACK_IN_ISR = FALSE   -- the callback will get run within the ISR
--
-- choose your data carrier
alias slip_serial_data is serial_hw_data
alias slip_data_available is serial_hw_data_available
--
-- Choose the size of your recieve buffer.
-- Should be the same as SLIP MTU if slip interrupts are not enabled
const byte QUEUE01_SIZE = 254
include queue01 -- include the queue/buffer library
alias slip_rx_buffer is queue01_nb  -- alias buffer for recieved data
--
-- Choose buffer to hold packet sizes (for interrupts only)
const byte QUEUE02_SIZE = 10
include queue02 -- include the queue/buffer library
alias slip_packet_size_buffer is queue02_nb     -- alias buffer for packet sizes
alias slip_packets_available is queue02_nr_used -- alias for number of packets avail
--
-- prototype for procedure defined in network.jal
procedure network_received_packet()
-- allias callback for when a full slip packet is recieved
alias slip_received_packet_callback is network_received_packet
--
include slip -- include the library
--
slip_init() -- init the slip library

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
;const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
;const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
;const NETWORK_USE_TCP = FALSE -- under development (not working)
;const NETWORK_USE_TCP_CALLBACKS = FALSE
--
var byte network_local_ip[4] = {192,168,2,1}                  -- IP address of PIC
;var byte network_local_ip[4] = {192,168,2,1}
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_SLIP
;const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
;include ethernet_mac
include ip_header
;include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp
--
const UDP_MAX_SOCKETS = 3 -- max number of udp connections (9 bytes ram per connection)
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const UDP_LOCAL_CLIENT_PORT = 1234   -- port of local UDP client
const UDP_REMOTE_SERVER_PORT = 251   -- port of remote UDP server
network_set_remote_ip(192,168,2,2)      -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

;   -- setup TCP
;   const TCP_MAX_SOCKETS = 2
;   ;const TCP_MAX_CONNECTIONS  = 1
;   const TCP_SERVER = TRUE        -- server mode
;   const TCP_SERVER_PORT = 33891  -- server port
;   include tcp

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led = !led -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

;   -- If it is our client connection
;   -- you can use this method if the server reply's using
;   -- the same source port as the server.
;   -- This is untested since my PC programming software does not
;   -- do this (yet).
;   if socket == udp_conn_1 then
;       print_crlf(serial_data)
;       var byte sending_udp[] = "Welcome client!" -- print a message
;       print_string(serial_data,sending_udp)
;       print_crlf(serial_data)
;
;      -- do something with the data, we'll print it to serial port
;      var word step
;      for udp_data_size using step loop               -- for each byte in packet
;         serial_data = udp_data[step]
;      end loop
;   end if

   -- if it is our client connection
   -- if we had sent information to a server, and the server replyed on same port.
   if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
      udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

       -- maybe you want to talk back to the client?
       -- send a reply message
       udp_data[0] = "T"
       udp_data[1] = "H"
       udp_data[2] = "A"
       udp_data[3] = "N"
       udp_data[4] = "K"
       udp_data[5] = "S"
       udp_data[6] = "!"

       print_crlf(serial_data)
       var byte sending_udp[] = "Sending reply UDP data" -- print a message
       print_string(serial_data,sending_udp)
       print_crlf(serial_data)
       udp_send(socket,7)        -- send 7 bytes data to socket
   end if

   ;if it is anything else

   udp_socket_remove(socket) -- remove the socket

   print_crlf(serial_data)
end procedure

;   --------------------------------------------------------------------------------
;   -- Receive UDP data. Minumum data size is 18 bytes. UDP_LOCAL_CLIENT_PORT is
;   -- the PIC's port.
;   --------------------------------------------------------------------------------
;   procedure tcp_receive_callback(byte in connection_number, word in tcp_client_port,word in tcp_server_port, word in tcp_data_size) is
;      -- send some info via serial port about our packet
;      print_crlf(serial_data)
;      print_crlf(serial_data)
;      const byte str2[] = "TCP data received. port: "
;      print_string(serial_data,str2)
;      print_word_dec(serial_data, tcp_client_port)
;      const byte str_size[] = ", bytes: "
;      print_string(serial_data,str_size)
;      print_word_dec(serial_data, tcp_data_size)
;      print_crlf(serial_data)
;
;
;      -- check the TCP port number
;      if tcp_client_port == 33891 then
;
;         -- do something with the data, we'll print it to serial port
;         var word step = ETHERNET_HEADER_SIZE + ip_header_size
;         for (NETWORK_DATA_SIZE - (ETHERNET_HEADER_SIZE + ip_header_size)) loop -- for each byte in packet
;            print_byte_hex(serial_data,network_data[step])
;            serial_data = " "
;            step = step + 1
;         end loop
;
;      end if
;
;   end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

if defined(arp_get_gateway_mac) then
   -- get the MAC of the gateway we will be talking to
   network_set_remote_ip(192,168,1,1) -- ip address of your PC or router
   ;network_set_remote_ip(192,168,2,2)
   -- print message
   var byte sending_arp[] = "sending arp request, waiting for reply..."
   print_string(serial_data,sending_arp)
   print_crlf(serial_data)
   --
   if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
      arp_get_gateway_mac(1_000)
   end if
   --
   if arp_packet_recieved == TRUE then
      print_crlf(serial_data)
      var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
      print_string(serial_data,get_arp)
      print_crlf(serial_data)
      --
      print_byte_hex(serial_data,network_remote_mac[0])
      serial_data = "-"
      print_byte_hex(serial_data,network_remote_mac[1])
      serial_data = "-"
      print_byte_hex(serial_data,network_remote_mac[2])
      serial_data = "-"
      print_byte_hex(serial_data,network_remote_mac[3])
      serial_data = "-"
      print_byte_hex(serial_data,network_remote_mac[4])
      serial_data = "-"
      print_byte_hex(serial_data,network_remote_mac[5])
      print_crlf(serial_data)
      print_crlf(serial_data)
   else
      print_crlf(serial_data)
      var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
      print_string(serial_data,arp_error)
      print_crlf(serial_data)
   end if
end if

-- uncomment if you are using WIN XP slip connection
if NETWORK_LINK_LAYER == NETWORK_SLIP then
   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
   while !serial_hw_data_available loop
   end loop

   -- reply with "CLIENTSERVER" to initiate connection
   const byte str1[] = "CLIENTSERVER"   -- define a string
   print_string(serial_hw_data, str1)   -- send via serial port
end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then
       -- print a message
       print_crlf(serial_data)
       var byte sending_ping[] = "sending ping"
       print_string(serial_data,sending_ping)
       print_crlf(serial_data)

      ;network_set_remote_ip(74,125,226,18) -- ping google's ip address
      network_set_remote_ip(192,168,2,2)   -- ping a computer
      ;network_set_remote_ip(192,168,2,2) -- ping a computer
      ;network_set_remote_ip(192,168,2,25) -- ping a computer
      ;network_set_remote_ip(192,168,1,1)   -- ping router
      icmp_send_echo()

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- send arp when button is pressed
   if button2 == LOW then

       -- crlf
       print_crlf(serial_data)

       -- set remote ip
;       network_set_remote_ip(192,168,2,255)
;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,2,25)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info
       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

;      -- EXAMPLE 2: Send an array
;      -- more ram usage and less cpu cycles then udp_send()
;      -- send the data (source port, destination port, data)
;      --
;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
;      --
;      print_udp_socket_info(1,udp_conn_1) -- print socket info
;      --
;      var byte test[] = "HELLO WORLD"                   -- set data
;      if udp_error == 0 then                            -- if there are no errors
;         var byte sending_udp[] = "Sending UDP data"    -- print a message
;         print_string(serial_data,sending_udp)
;         print_crlf(serial_data)
;         udp_send_array(udp_conn_1,test)                -- send udp data
;      else
;         var byte sending_udp[] = "UDP error occurred"  -- print a message
;         print_string(serial_data,sending_udp)
;         print_crlf(serial_data)
;      end if
;      ;udp_socket_remove(udp_conn_1)                 -- remove

     while button2 == LOW loop
        _usec_delay(100_000)
     end loop

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: networking.jal


network_set_remote_ip - JALlib Procedures Help

network_set_remote_ip JALLIB PROCEDURE

Signature

procedure network_set_remote_ip(byte in ip_0,byte in ip_1,byte in ip_2,byte in ip_3) is

Description

set remote ip address

Include

To use this procedure, include the library:

include networking

Parameters

  • ip_0 - byte in
  • ip_1 - byte in
  • ip_2 - byte in
  • ip_3 - byte in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: networking.jal


networking.jal - JALLIB Library Documentation

networking.jal JALLIB LIBRARY

Title

Networking main procedures BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

recieves packets and forwards them to the next next protocol

Sources

http://www.comptechdoc.org/independent/networking/protocol/protnet.html
notes:
Wireshark is awsome! http://www.wireshark.org/
Requirements for network adapter (ethernet device, wifi device, SLIP, etc.)
1. Add aliases to network_globals.jal
RECEIVING PACKETS:
1. User polls network_poll() procedure
2. If a packet is recieved, it is passed to network_received_packet,
the packet size is checked, then sent to the next level/protocol.
3. If it is Ethernet, it goes to ethernet_read_packet(), then
ip_header_read_packet(). If it is SLIP, it goes directly
to ip_header_read_packet()
4. The packet is then sent to the next protocol's read_packet procedure.
5. A callback procedure is run in the user program.
TRANSMITTING PACKETS:
1. User calls a procedure from a protocol
2. That protocol will call other protocols to create an Ethernet
header (if Ethernet), ip_header, and whatever is needed by the
top level protocol.
3. The packet is sent onto the network.
TODO:

defined in constants_jallib.jal

error checking (temporary untill next jallib pack release)

------------------------------------------------------------------------------
setup the link layer drivers. aliases of network device variables & procedures
------------------------------------------------------------------------------
constant settings for slip networking

Constants and Variables

network_var_offset - var word = 0
network_packet_size - var word = 0
DEBUG_MASTER_ENABLE - const bit = FALSE -- enables debugging
enables debugging

Routines

  • network_byte'get - Function returns byte
  • network_byte'put - Procedure
  • network_byte_x_6'get - Function returns dword
  • network_byte_x_6'put - Procedure
  • network_checksum_16_byte_calc - Function returns word
  • network_checksum_16_byte_verify - Function returns bit
  • network_clear_rx_queue - Procedure
  • network_dword'get - Function returns dword
  • network_dword'put - Procedure
  • network_get_packet - Procedure
  • network_get_packet - Procedure
  • network_poll - Procedure
  • network_received_packet - Procedure
  • network_send_packet - Procedure
  • network_send_packet - Procedure
  • network_set_remote_ip - Procedure
  • network_set_remote_mac - Procedure
  • network_switch_dword_bytes - Procedure
  • network_switch_word_bytes - Procedure
  • network_word'get - Function returns word
  • network_word'put - Procedure


nokia_clear_screen - JALlib Procedures Help

nokia_clear_screen JALLIB PROCEDURE

Signature

procedure nokia_clear_screen() is

Description

Clear the LCD data memory

Include

To use this procedure, include the library:

include glcd_nokia_5110

Parameters

None

Return Value

None

Example

From sample file: 18f4550_glcd_nokia_5110_image.jal

-- Title: GLCD Nokia 3310/5110 image demo sample. Drawing images.
-- Author: Rob Jansen, Copyright (c) 2021..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD for the Nokia 5110 display.
--              It demonstrates  the drawing of images on the display including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 84 x 48 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--

include 18f4550
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL
pragma target WDT       control    -- watchdog
pragma target LVP       enabled    -- use low Voltage Programming
pragma target MCLR      external   -- reset externally
WDTCON_SWDTEN = off                -- no watchdog

enable_digital_io()

-- Pin assignment for the Nokia display.
alias nokia_sclk       is pin_b6    --  assign nokia clock
alias nokia_sda        is pin_b4    --  assign nokia serial data in
alias nokia_res        is pin_c0    --  assign nokia reset
alias nokia_dc         is pin_c2    --  assign nokia data/commant
-- The chip select for the Nokia can be connected to ground to save a pin. If
-- to be controlled by the library then it can be defined here but all the
-- library does is enable the chip select when nokia_init() is called. If
-- used then define the following:
--    alias nokia_cs         is pin_c1    --  assign nokia chip select
--    pin_c1_direction = output

pin_b6_direction = output
pin_b4_direction = output
pin_c2_direction = output
pin_c0_direction = output

-- include glcd_6x8_font
include glcd_nokia_5110
nokia_init()

include glcd_common
include delay
include print
include glcd_5x7_font
include glcd_font

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Filled oval 84 x 48
const byte oval[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0xC0, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xF8, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE,
    0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xC0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFE, 0xFC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x1F,
    0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
    0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,
    0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[], byte in x_size, byte in y_size) is
   glcd_clear_cache()
   nokia_clear_screen()
   glcd_draw_image(image,0,0,x_size,y_size)
   glcd_cache_update()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   glcd_clear_cache()
   nokia_clear_screen()
     for 3 loop
      glcd_draw_image(battery_00,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_25,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_50,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   glcd_clear_cache()
   nokia_clear_screen()
    for 4 loop
      glcd_draw_image(envelope,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(envelope,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
    end loop
end procedure

-- Default pen color.
glcd_pen_color = GLCD_BLACK
glcd_font_use(FONT_5X7)
print_string(glcd,"Image demo !")
delay_1s(2)

forever loop

   -- Draw the images, one default, one inverted.
   draw_an_image(jal_logo,84,48)
   draw_an_image(marilyn,84,48)
   draw_an_image(oval,84,48)
   -- Show the battery charging.
   draw_battery_charging()
   -- Show drawing 2 icons dranw independently.
   draw_two_icons()

   -- Now display the inverted/normal image.
    if (glcd_pen_color == GLCD_BLACK)
    then
       glcd_pen_color = GLCD_WHITE
    else
       glcd_pen_color = GLCD_BLACK
    end if

end loop

Generated by JALlib CHM Help System | Source: glcd_nokia_5110.jal


nokia_goto - JALlib Procedures Help

nokia_goto JALLIB PROCEDURE

Signature

procedure nokia_goto(byte in x, byte in y) is

Description

Set the current position for data (x = 0->83, y = 0->5)

Include

To use this procedure, include the library:

include glcd_nokia_5110

Parameters

  • x - byte in
  • y - byte in

Return Value

None

Example

From sample file: 18f4550_glcd_nokia_5110_gfx.jal

-- Title: GLCD Nokia 3310/5110 demo sample, pixel based stuff
-- Author: Sbastien Lelong, Copyright (c) 2011..2019, all rights reserved.
-- Adapted-by: Rob Jansen
-- Compiler: 2.5r3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: simple demo showing how to use GLCD Nokia 3310/5110. This is
-- a graphic LCD, widely commonly in DIY projects. This sample shows some
-- basic usage with pixels related stuff demo like: plotting pixels, lines, etc...
--
-- This file has been generated by hand (manually maintained)
--

include 18f4550
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL

pragma target WDT  control         -- watchdog
WDTCON_SWDTEN = off                -- no watchdog

pragma target LVP  enabled         -- allow Low Voltage Programming
pragma target MCLR external        -- reset externally

enable_digital_io()

include delay

-- Pins to control the Nokia LCD.
alias nokia_sclk       is pin_b6    --  assign nokia clock
alias nokia_sda        is pin_b4    --  assign nokia serial data in
alias nokia_res        is pin_c0    --  assign nokia reset
alias nokia_dc         is pin_c2    --  assign nokia data/commant
-- The chip select for the Nokia can be connected to ground to save a pin. If
-- to be controlled by the library then it can be defined here but all the
-- library does is enable the chip select when nokia_init() is called. If
-- used then define the following:
--    alias nokia_cs         is pin_c1    --  assign nokia chip select
--    pin_c1_direction = output

pin_b6_direction = output
pin_b4_direction = output
pin_c2_direction = output
pin_c0_direction = output

include print

include glcd_5x7_font
include glcd_font
glcd_font_use(FONT_5X7)

-- GLCD lib
include glcd_nokia_5110
nokia_init()
include glcd_common

const byte tline[] = "Line"
const byte tbox[] = "Box"
const byte tcircle[] = "Circle"
const byte tellipse[] = "Ellipse"

forever loop
   glcd_clear_cache()
   nokia_clear_screen()
   nokia_goto(0,0)
   print_string(glcd,tline)
   delay_1s(2)
   glcd_line(10,10,60,40)
   glcd_cache_update()
   delay_1s(2)

   glcd_clear_cache()
   nokia_clear_screen()
   nokia_goto(0,0)
   print_string(glcd,tbox)
   delay_1s(2)
   glcd_box(4,4,80,40)
   glcd_cache_update()
   delay_1s(2)

   glcd_clear_cache()
   nokia_clear_screen()
   nokia_goto(0,0)
   print_string(glcd,tcircle)
   delay_1s(2)
   glcd_circle(40,25,20)
   glcd_cache_update()
   delay_1s(2)

   glcd_clear_cache()
   nokia_clear_screen()
   nokia_goto(0,0)
   print_string(glcd,tellipse)
   delay_1s(2)
   glcd_ellipse(40,20,30,10)
   glcd_cache_update()
   delay_1s(2)

end loop

Generated by JALlib CHM Help System | Source: glcd_nokia_5110.jal


nokia_init - JALlib Procedures Help

nokia_init JALLIB PROCEDURE

Signature

procedure nokia_init() is

Description

Send LCD initialization commands

Include

To use this procedure, include the library:

include glcd_nokia_5110

Parameters

None

Return Value

None

Example

From sample file: 18f4550_glcd_nokia_5110_image.jal

-- Title: GLCD Nokia 3310/5110 image demo sample. Drawing images.
-- Author: Rob Jansen, Copyright (c) 2021..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD for the Nokia 5110 display.
--              It demonstrates  the drawing of images on the display including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 84 x 48 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--

include 18f4550
pragma target clock 48_000_000
-- magical statements: using a 20MHz Xtal, you can run @48MHz !
pragma target PLLDIV    P5
pragma target CPUDIV    P1
pragma target USBDIV    P2
pragma target OSC       HS_PLL
pragma target WDT       control    -- watchdog
pragma target LVP       enabled    -- use low Voltage Programming
pragma target MCLR      external   -- reset externally
WDTCON_SWDTEN = off                -- no watchdog

enable_digital_io()

-- Pin assignment for the Nokia display.
alias nokia_sclk       is pin_b6    --  assign nokia clock
alias nokia_sda        is pin_b4    --  assign nokia serial data in
alias nokia_res        is pin_c0    --  assign nokia reset
alias nokia_dc         is pin_c2    --  assign nokia data/commant
-- The chip select for the Nokia can be connected to ground to save a pin. If
-- to be controlled by the library then it can be defined here but all the
-- library does is enable the chip select when nokia_init() is called. If
-- used then define the following:
--    alias nokia_cs         is pin_c1    --  assign nokia chip select
--    pin_c1_direction = output

pin_b6_direction = output
pin_b4_direction = output
pin_c2_direction = output
pin_c0_direction = output

-- include glcd_6x8_font
include glcd_nokia_5110
nokia_init()

include glcd_common
include delay
include print
include glcd_5x7_font
include glcd_font

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Filled oval 84 x 48
const byte oval[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
    0xC0, 0xC0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xF8, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFE,
    0xFE, 0xFE, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xC0, 0xE0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
    0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFE, 0xFC, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F, 0x1F,
    0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
    0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,
    0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[], byte in x_size, byte in y_size) is
   glcd_clear_cache()
   nokia_clear_screen()
   glcd_draw_image(image,0,0,x_size,y_size)
   glcd_cache_update()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   glcd_clear_cache()
   nokia_clear_screen()
     for 3 loop
      glcd_draw_image(battery_00,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_25,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_50,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,0,0,84,48)
      glcd_cache_update()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   glcd_clear_cache()
   nokia_clear_screen()
    for 4 loop
      glcd_draw_image(envelope,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(envelope,50,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
      glcd_draw_image(arrow,10,10,24,24)
      glcd_cache_update()
      _usec_delay(500_000)
    end loop
end procedure

-- Default pen color.
glcd_pen_color = GLCD_BLACK
glcd_font_use(FONT_5X7)
print_string(glcd,"Image demo !")
delay_1s(2)

forever loop

   -- Draw the images, one default, one inverted.
   draw_an_image(jal_logo,84,48)
   draw_an_image(marilyn,84,48)
   draw_an_image(oval,84,48)
   -- Show the battery charging.
   draw_battery_charging()
   -- Show drawing 2 icons dranw independently.
   draw_two_icons()

   -- Now display the inverted/normal image.
    if (glcd_pen_color == GLCD_BLACK)
    then
       glcd_pen_color = GLCD_WHITE
    else
       glcd_pen_color = GLCD_BLACK
    end if

end loop

Generated by JALlib CHM Help System | Source: glcd_nokia_5110.jal


now.jal - JALLIB Library Documentation

now.jal JALLIB LIBRARY

Title

Now, initialises time and date in a PIC with an RTC

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved., Adapted-by:

Compiler

>=2.4h

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library sets the time to the system time + 1 minute,
typically the time it takes to compile and program the PIC.
This library should be generated just before compiling by executing timeset.py


nrf24_get_data - JALlib Procedures Help

nrf24_get_data JALLIB FUNCTION

Signature

function nrf24_get_data(byte out pipe, byte in out how_long) return bit is

Description

Checks if data is received, copies it to the nrf24_read_buffer[] and returns
TRUE when data is available.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

  • pipe - byte out
  • how_long - byte in out

Return Value

bit - Function return value

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_init - JALlib Procedures Help

nrf24_init JALLIB PROCEDURE

Signature

procedure nrf24_init() is

Description

Initializes the SPI interface to communicate with the nRF24L01+ module and
initializes the module after which the module is powered down. The procedure
also waits for power up time to pass and initializes the module as follows:
-) Set CRC coding scheme to 2 bytes.
-) Set transmit/receive address width to 5 bytes (default).
-) Sets the module receive address to NRF24_RECEIVE_ADDR on pipe 1 including
the payload size to NRF24_PAYLOAD_SIZE.
-) Enable plus mode which means setting auto acknowledge on all pipes.
-) Set the retransmit delay 750 us and the retransmit count to 5.
-) Set RF Channel to 2 (default).
-) Set bitrate to 2 Mbits/s (default).
-) Set RF TX power power to 0 dBm (default).
-) Enable dynamic payload length.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

None

Return Value

None

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_power_up_rx - JALlib Procedures Help

nrf24_power_up_rx JALLIB PROCEDURE

Signature

procedure nrf24_power_up_rx() is

Description

Power up the receiver and clear all pending RX and TX status bits.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

None

Return Value

None

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_power_up_tx - JALlib Procedures Help

nrf24_power_up_tx JALLIB PROCEDURE

Signature

procedure nrf24_power_up_tx() is

Description

Power up the transmitter and clear all pending RX and TX status bits.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

None

Return Value

None

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_send_data - JALlib Procedures Help

nrf24_send_data JALLIB PROCEDURE

Signature

procedure nrf24_send_data(byte in data[], byte in length) is

Description

Sends the number of data bytes given in length from the given buffer. When
dynamic payload is not active the procedure will fill the remaining payload
with '00' as to always start a transmission.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

  • data[] - byte in
  • length - byte in

Return Value

None

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_set_rx_pipe - JALlib Procedures Help

nrf24_set_rx_pipe JALLIB PROCEDURE

Signature

procedure nrf24_set_rx_pipe(byte in pipe, byte in addr[]) is

Description

Sets the receiving address for a pipe number, and sets payload width as well.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

  • pipe - byte in
  • addr[] - byte in

Return Value

None

Example

From sample file: 16f1825_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2019..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program sends a message once every two seconds to two different
--              nRF24L01+ devices and will print any received message from these
--              devices. The pipe from which the message was received will be
--              printed as to show from which device the message was received.
--              This sample file uses SPI hardware 1 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1823_nrf24l01.jal (using SPI hardware 1)
--              or 16f1829_nrf24l01.jal (using SPI hardware 2) for the counter
--              part of this sample program which is the receiver of the message
--              sent.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
alias serial is serial_hw_data
serial_hw_init()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 1.
-- Note that you can also use SPI hardware 2 if your PIC supports that.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_C0
   alias nrf24_spi_sdi is pin_C1
   alias nrf24_spi_sdo is pin_C2
else
   -- Hardware SPI, setup hardware SPI 1 interface.
   include spi_host_hw
   alias nrf24_spi_exchange is spi_host_hw_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other reruired nRF24L01 pin aliases
alias nrf24_spi_sck_direction is pin_C0_direction -- Pin 10 for 14 pin DIP
alias nrf24_spi_sdi_direction is pin_C1_direction -- Pin  9 for 14 pin DIP.
alias nrf24_spi_sdo_direction is pin_C2_direction -- Pin  8 for 14 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 14 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C4                     -- Pin  6 for 14 pin DIP.
alias nrf24_csn_pin_direction is pin_C4_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5]   = {0x66, 0x77, 0x88, 0x99, 0xAA}
const byte NRF24_RECEIVE_ADDR[5]    = {0x01, 0x22, 0x33, 0x44, 0x55}
-- Addresses for second device. For the receive address, only the Least
-- Significant Byte (LSB) is relevant. The rest of the receive address is equal
-- to NRF24_RECEIVE_ADDR, so {LSB, x, x, x, x}.
const byte NRF24_TRANSMIT_ADDR_2[5] = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}
const byte NRF24_RECEIVE_ADDR_2[5]  = {0x02, 0x22, 0x33, 0x44, 0x55}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)
-- Receive address for second device on second pipe.
nrf24_set_rx_pipe(2, NRF24_RECEIVE_ADDR_2)

include print

const byte start[] = "Test program for nRF24L01+\r\n"
const byte hello[] = "Hello World!"
var byte counter, index, pipe
var byte device_to_send_to
var word timer
var bit sending_data

-- Show welcome message.
print_string(serial,start)
print_crlf(serial)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop

   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   if (timer >= 2_000) then
      print_crlf(serial)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial,"Sending data to device 1 ... ")
         nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial,"Sending data to device 2 ... ")
         nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR_2)
         device_to_send_to = 1
      end if
      -- Enable the transmitter and send the data.
      nrf24_power_up_tx()
      nrf24_send_data(hello, count(hello))
      sending_data = TRUE
      timer = 0
   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf24_tx_ready() then
      -- Transmission done, check if successful.
      if nrf24_tx_ok() then
         print_string(serial,"Transmission OK! \r\n")
      else
         print_string(serial,"Transmission failed! \r\n")
      end if
      print_crlf(serial)
      print_string(serial,"Enabling receiver ... \r\n")
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices.
   if nrf24_get_data(pipe, counter) then
       print_crlf(serial)
       print_string(serial,"Receiving data from pipe (device) ")
      -- Print pipe number in ASCII and then the data.
      serial = pipe + 0x30
      print_string(serial,": ")
      for counter using index loop
         serial = nrf24_read_buffer[index]
      end loop
      print_crlf(serial)
  end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_set_transmit_address - JALlib Procedures Help

nrf24_set_transmit_address JALLIB PROCEDURE

Signature

procedure nrf24_set_transmit_address(byte in addr[]) is

Description

Sets the transmitting address and pipe 0 as to enable auto acknowledge.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

  • addr[] - byte in

Return Value

None

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_spi_exchange - JALlib Procedures Help

nrf24_spi_exchange JALLIB FUNCTION

Signature

function nrf24_spi_exchange(byte in data) return byte is

Description

SPI interface done in software using same the function name as hardware SPI.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

  • data - byte in

Return Value

byte - Function return value

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_tx_ok - JALlib Procedures Help

nrf24_tx_ok JALLIB FUNCTION

Signature

function nrf24_tx_ok() return bit is

Description

Returns the the status of the last transmission. If the maximum number of
retries were used FALSE is returned indicating a tranmission failure,
otherwise TRUE is returned indicating a succesful transmission.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24_tx_ready - JALlib Procedures Help

nrf24_tx_ready JALLIB FUNCTION

Signature

function nrf24_tx_ready() return bit is

Description

Check if the transmission status and returns TRUE when ready.

Include

To use this procedure, include the library:

include nrf24l01

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1829_nrf24l01.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF24L01+
--
-- Author: Rob Jansen, Copyright (c) 2025..2025 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This program waits for a message to be received from another
--              nRF24L01 device, adds 'Reply : ' to the received message and
--              returns the modified message back to the tranmit address.
--              Three LEDs are used to indicate the status of the transmission:
--              -) Yellow LED. A message was received. This LED will blink shortly.
--              -) Red LED. The transmission of the return message failed.
--              -) Green LED. The transmission of the return message went OK.
--              Next to that the program uses a test input pin for forcing the
--              transmission of a "Hello" message to the transmit address.
--              This message will be repeated as long as the test input pin is
--              held LOW. In this case the yellow LED will also blink with each
--              message sent.
--              This sample file uses SPI hardware 2 but also shows how to set
--              it up for using the nRF24L01+ using SPI software.
--
-- Notes:       See sample program 16f1825_nrf24l01.jal for the counter part of
--              this sample program, the transmitter of the original message.
--
--              Some hardware related information:
--              -) The nRF24L01+ operates at a supply voltage of 3.3 Volt but
--                 can interface directly with a PIC operating at 5 Volt.
--              -) The nRF24L01+ is very sensitive to fluctuations on the power
--                 supply. Make sure you connect a capacitor of 100 uF close
--                 to the the power lines of the nRF24L01+
--
include 16f1829

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- No low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUB = 0b1111_0000
WPUC = 0b1111_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- Select SPI hardware or use software SPI. Software SPI gives you more
-- flexibility in which pins you want to use.
-- const NRF24_SOFTWARE_SPI = TRUE -- Remove comments to enable software spi.

-- The 'defined' below is only added to show what is needed when using either
-- software SPI or hardware SPI. This example shows the use of SPI hardware 2.
if defined(NRF24_SOFTWARE_SPI) then
   -- These are only needed for software SPI. Pins can be assigned to any port
   -- but keep the pin direction aliases in line.
   alias nrf24_spi_sck is pin_B7
   alias nrf24_spi_sdi is pin_B5
   alias nrf24_spi_sdo is pin_C1
else
   -- Hardware SPI, setup hardware SPI 2 interface.
   include spi_host_hw2
   alias nrf24_spi_exchange is spi_host_hw2_exchange
   -- The maximim SPI clock frequency for the nRF24L01+ is 10 MHz so if the
   -- target clock of the PIC is above 40 MHz use SPI_RATE_FOSC_16.
   spi2_init(SPI_MODE_00, SPI_RATE_FOSC_4)
end if
-- Other required nRF24L01 pin aliases.
alias nrf24_spi_sck_direction is pin_B7_direction -- Pin 10 for 20 pin DIP
alias nrf24_spi_sdi_direction is pin_B5_direction -- Pin 12 for 20 pin DIP.
alias nrf24_spi_sdo_direction is pin_C1_direction -- Pin 15 for 20 pin DIP.
alias nrf24_ce_pin  is pin_C3                     -- Pin  7 for 20 pin DIP.
alias nrf24_ce_pin_direction is pin_C3_direction
alias nrf24_csn_pin is pin_C6                     -- Pin  8 for 20 pin DIP.
alias nrf24_csn_pin_direction is pin_C6_direction

-- nRF24L01 transmit and receive address for this module must be defined, 5 bytes.
-- In case of more receive addresses only the first byte (LSB) of the receive
-- address is used, all remaining address bytes are the same.
-- Address must be given with Least Significant Byte first {LSB, .., .., .., MSB}.
const byte NRF24_TRANSMIT_ADDR[5] = {0x01, 0x22, 0x33, 0x44, 0x55}
const byte NRF24_RECEIVE_ADDR[5]  = {0x66, 0x77, 0x88, 0x99, 0xAA}
-- Note: If you want to make a second device using the counter part sample
-- program 16f1825_nrf24l01.jal then use these addresses instead when running
-- this sample program on your second device.
-- const byte NRF24_TRANSMIT_ADDR[5] = {0x02, 0x22, 0x33, 0x44, 0x55}
-- const byte NRF24_RECEIVE_ADDR[5]  = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF}

include nrf24l01
nrf24_init() -- This also sets the receive address on pipe 1.
nrf24_set_transmit_address(NRF24_TRANSMIT_ADDR)

-- LED on/off definitions.
const bit LED_ON = TRUE
const bit LED_OFF = FALSE

-- LED pin definitions.
alias led_red is pin_C5
pin_C5_direction = output
alias led_green is pin_A4
pin_A4_direction = output
alias led_yellow is pin_A5
pin_A5_direction = output

-- Test input pin, active low.
alias test_input is pin_A2
pin_A2_direction = input

const byte hello[] = "Hello World!"
const byte reply[] = "Reply : "
var byte buffer[NRF24_PAYLOAD_SIZE] -- Size defined in nRF24L01 library.
var byte counter, index_1, index_2, pipe
var bit sending_data

led_red = LED_ON
led_green = LED_ON
led_yellow = LED_ON

-- Send a welcome message at start up.
nrf24_power_up_tx()
nrf24_send_data(hello, count(hello))
while !nrf24_tx_ready() loop
   -- Empty: Wait for the transmission to complete.
end loop

led_red = LED_OFF
led_green = LED_OFF
led_yellow = LED_OFF

-- Let's wait for a message to arrive.
nrf24_power_up_rx()
sending_data = FALSE

forever loop

   -- Check for new data.
   if nrf24_get_data(pipe, counter) then
      led_yellow = LED_ON
      led_red = LED_OFF
      led_green = LED_OFF
      -- Add reply text to return message.
      for count(reply) using index_1 loop
         buffer[index_1] = reply[index_1]
      end loop
      index_1 = count(reply)
      index_2 = 0
      -- Now copy the received text but not more than the buffer size.
      while (counter > 0) & (index_1 < NRF24_PAYLOAD_SIZE) loop
         buffer[index_1] =  nrf24_read_buffer[index_2]
         counter = counter - 1
         index_1 = index_1 + 1
         index_2 = index_2 + 1
      end loop
      -- Send this message back.
      nrf24_power_up_tx()
      nrf24_send_data(buffer, index_1)
      sending_data = TRUE
   end if

   -- If transmission is done, indicate the result of the transmission and
   -- start the receiver again.
   if sending_data & nrf24_tx_ready() then
      led_yellow = LED_OFF
      if nrf24_tx_ok() then
         led_red = LED_OFF
         led_green = LED_ON
      else
         led_red = LED_ON
         led_green = LED_OFF
      end if
      -- Enable reiver again.
      nrf24_power_up_rx()
      sending_data = FALSE
   end if

   -- If the test pin is low we transmit the hello message (if not transmitting).
   if !sending_data & !test_input then
      -- Debounce and repetition time. Will repeat as long as input is low.
      _usec_delay(100_000)
      if !test_input then
         nrf24_power_up_tx()
         nrf24_send_data(hello, count(hello))
         sending_data = TRUE
         -- In this case we use the yellow LED to show that we are sending something.
         led_yellow = LED_ON
         led_red = LED_OFF
         led_green = LED_OFF
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf24l01.jal


nrf24l01.jal - JALLIB Library Documentation

nrf24l01.jal JALLIB LIBRARY

Title

nRF24L01+ library for wireless communication.

Author

Rob Jansen, Copyright (c) 2019..2025, all rights reserved., Adapted-by:

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Libray for wireless transmission and reception using the nRF24L01+.

Notes

The following pins must be defined by the main program before
including this library for both software SPI and hardware SPI:
-) alias nrf24_spi_sck_direction -- SCK to sck of nRF24L01+
-) alias nrf24_spi_sdi_direction -- SDI to MISO of nRF24L01+
-) alias nrf24_spi_sdo_direction -- SDO to MOSI of nRF24L01+
-) alias nrf24_ce_pin_direction -- To ce of nRF24L01+
-) alias nrf24_csn_pin_direction -- To csn of nRF24L01+
-) alias nrf24_ce_pin
-) alias nrf24_csn_pin
In addtion when using software SPI (see below):
-) alias nrf24_spi_sck
-) alias nrf24_spi_sdi
-) alias nrf24_spi_sdo
When using harware SPI (1 or 2) you need to include the SPI JAL
library and initialize the SPI inteface, example given for 1:
-) include spi_host_hw
-) alias nrf24_spi_exchange is spi_host_hw_exchange
And initialize the hardware SPI using MODE_00:
-) spi_init(SPI_MODE_00, SPI_RATE_FOSC_4)
Use SPI_RATE_FOSC_16 when the target clock is > 40 MHz.
Define the NRF24_RECEIVE_ADDR using the correct number of bytes
(default is 5) in an array with the Least Significant Byte (LSB)
first. This address must be defined before including this library.
Example (byte 0x01 is LSB):
-) const byte NRF24_RECEIVE_ADDR[5] = {0x01, 0xAA, 0xBB, 0xCC, 0xDD}
In case more receive addresses are used on other pipes, only the LSB
of this new 5-bytes address is used, the other bytes remain the same
as the original NRF24_RECEIVE_ADDR.
The maximum payload size is set to NRF24_PAYLOAD_SIZE, which also
creates are receive buffer called 'nrf24_read_buffer' of the same
size. The default size is 25 bytes. To change this use:
-) const byte NRF24_PAYLOAD_SIZE = <your size>.
The payload size range is between 1 and 32 (= NRF24_MAX_PAYLOAD).
This library also implemented a software SPI interface.
In order to use this define the following:
-) const NRF24_SOFTWARE_SPI = TRUE
In this case the section about hardware SPI initialization is
not needed.
Some hardware related information:
-) The nRF24L01+ operates at a supply voltage of 3.3 Volt but can
interface directly with a PIC operating at 5 Volt.
-) The nRF24L01+ is very sensitive to fluctuations on the power
supply. Make sure you connect a capacitor of 100 uF close to the
the power lines of the nRF24L01+

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Data rates. Default is 2 Mbits/s.

Sources

https://infocenter.nordicsemi.com/pdf/nRF24L01P_PS_v1.0.pdf
Partly based on the draft library of Sebastien LeLong. Completed,
extended and adapted to enable backward compatibility with older
nRF24XX devices. Draft library version can be found at:
https://github.com/sirloon/jaluino/blob/master/lib/nrf24l01.jal

Constants and Variables

NRF24_DATA_RATE_250KBPS - const byte = 0b0010_0000
NRF24_DATA_RATE_1MBPS - const byte = 0b0000_0000
NRF24_DATA_RATE_2MBPS - const byte = 0b0000_1000
NRF24_POWER_LEVEL_MIN - const byte = 0b000_0000 -- -18dBm
-18dBm
NRF24_POWER_LEVEL_LOW - const byte = 0b000_0010 -- -12dBm
-12dBm
NRF24_POWER_LEVEL_MED - const byte = 0b000_0100 -- -6dBm
-6dBm
NRF24_POWER_LEVEL_MAX - const byte = 0b000_0110 -- 0dBm
0dBm
NRF24_ADDR_WIDTH_3 - const byte = 3
NRF24_ADDR_WIDTH_4 - const byte = 4
NRF24_ADDR_WIDTH_5 - const byte = 5
NRF24_PAYLOAD_SIZE - const byte = 25
NRF24_MAX_PAYLOAD - const byte = 32
NRF24_CONFIG_REG - const byte = 0x00
NRF24_EN_AA - const byte = 0x01
NRF24_EN_RXADDR - const byte = 0x02
NRF24_SETUP_AW - const byte = 0x03
NRF24_SETUP_RETR - const byte = 0x04
NRF24_RF_CH - const byte = 0x05
NRF24_RF_SETUP - const byte = 0x06
NRF24_STATUS - const byte = 0x07
NRF24_OBSERVE_TX - const byte = 0x08
NRF24_CD - const byte = 0x09
NRF24_RX_ADDR_P0 - const byte = 0x0A
NRF24_RX_ADDR_P1 - const byte = 0x0B
NRF24_RX_ADDR_P2 - const byte = 0x0C
NRF24_RX_ADDR_P3 - const byte = 0x0D
NRF24_RX_ADDR_P4 - const byte = 0x0E
NRF24_RX_ADDR_P5 - const byte = 0x0F
NRF24_TX_ADDR - const byte = 0x10
NRF24_RX_PW_P0 - const byte = 0x11
NRF24_RX_PW_P1 - const byte = 0x12
NRF24_RX_PW_P2 - const byte = 0x13
NRF24_RX_PW_P3 - const byte = 0x14
NRF24_RX_PW_P4 - const byte = 0x15
NRF24_RX_PW_P5 - const byte = 0x16
NRF24_FIFO_STATUS - const byte = 0x17
NRF24_DYNPD - const byte = 0x1C
NRF24_FEATURE - const byte = 0x1D
NRF24_MASK_RX_DR - const byte = 6
NRF24_MASK_TX_DS - const byte = 5
NRF24_MASK_MAX_RT - const byte = 4
NRF24_EN_CRC - const byte = 3
NRF24_CRCO - const byte = 2
NRF24_PWR_UP - const byte = 1
NRF24_PRIM_RX - const byte = 0
NRF24_ENAA_P5 - const byte = 5
NRF24_ENAA_P4 - const byte = 4
NRF24_ENAA_P3 - const byte = 3
NRF24_ENAA_P2 - const byte = 2
NRF24_ENAA_P1 - const byte = 1
NRF24_ENAA_P0 - const byte = 0
NRF24_ERX_P5 - const byte = 5
NRF24_ERX_P4 - const byte = 4
NRF24_ERX_P3 - const byte = 3
NRF24_ERX_P2 - const byte = 2
NRF24_ERX_P1 - const byte = 1
NRF24_ERX_P0 - const byte = 0
NRF24_AW - const byte = 0
NRF24_ARD - const byte = 4
NRF24_ARC - const byte = 0
NRF24_CH - const byte = 0
NRF24_CONT_WAVE - const byte = 7
NRF24_RF_DR_LOW - const byte = 5
NRF24_PLL_LOCK - const byte = 4
NRF24_RF_DR_HIGH - const byte = 3
NRF24_RF_PWR - const byte = 1
NRF24_LNA_HCURR - const byte = 0
NRF24_RX_DR - const byte = 6
NRF24_TX_DS - const byte = 5
NRF24_MAX_RT - const byte = 4
NRF24_RX_P_NO - const byte = 1
NRF24_TX_FULL - const byte = 0
NRF24_PLOS_CNT - const byte = 4
NRF24_ARC_CNT - const byte = 0
NRF24_TX_REUSE - const byte = 6
NRF24_FIFO_FULL - const byte = 5
NRF24_TX_EMPTY - const byte = 4
NRF24_RX_FULL - const byte = 1
NRF24_RX_EMPTY - const byte = 0
NRF24_EN_DPL - const byte = 2
NRF24_DPL_P5 - const byte = 5
NRF24_DPL_P4 - const byte = 4
NRF24_DPL_P3 - const byte = 3
NRF24_DPL_P2 - const byte = 2
NRF24_DPL_P1 - const byte = 1
NRF24_DPL_P0 - const byte = 0
NRF24_R_REGISTER - const byte = 0x00
NRF24_W_REGISTER - const byte = 0x20
NRF24_REGISTER_MASK - const byte = 0x1F
NRF24_R_RX_PAYLOAD - const byte = 0x61
NRF24_W_TX_PAYLOAD - const byte = 0xA0
NRF24_FLUSH_TX - const byte = 0xE1
NRF24_FLUSH_RX - const byte = 0xE2
NRF24_REUSE_TX_PL - const byte = 0xE3
NRF24_R_RX_PL_WID - const byte = 0x60
NRF24_NOP - const byte = 0xFF
NRF24_ACTIVATE - const byte = 0x50
NRF24_CONFIG - const byte = ((1<

Routines

  • _nrf24_flush_rx - Procedure
  • _nrf24_flush_tx - Procedure
  • _nrf24_get_dynamic_payload_size - Function returns byte
  • _nrf24_get_status - Function returns byte
  • _nrf24_read_byte_register - Function returns byte
  • _nrf24_write_array_register - Procedure
  • _nrf24_write_byte_register - Procedure
  • nrf24_carrier_detected - Function returns bit
  • nrf24_data_available - Function returns bit
  • nrf24_disable_dynamic_payload - Procedure
  • nrf24_enable_compatibility_mode - Procedure
  • nrf24_enable_dynamic_payload - Procedure
  • nrf24_get_data - Function returns bit
  • nrf24_init - Procedure
  • nrf24_power_down - Procedure
  • nrf24_power_up_rx - Procedure
  • nrf24_power_up_tx - Procedure
  • nrf24_print_address_register - Procedure
  • nrf24_print_byte_register - Procedure
  • nrf24_print_config - Procedure
  • nrf24_print_details - Procedure
  • nrf24_print_en_aa - Procedure
  • nrf24_print_observe_tx - Procedure
  • nrf24_print_rf_setup - Procedure
  • nrf24_print_setup_retr - Procedure
  • nrf24_print_status - Procedure
  • nrf24_send_data - Procedure
  • nrf24_set_address_width - Procedure
  • nrf24_set_auto_retransmit_count - Procedure
  • nrf24_set_auto_retransmit_delay - Procedure
  • nrf24_set_data_rate - Procedure
  • nrf24_set_power_level - Procedure
  • nrf24_set_rf_channel - Procedure
  • nrf24_set_rx_pipe - Procedure
  • nrf24_set_transmit_address - Procedure
  • nrf24_spi_exchange - Function returns byte
  • nrf24_tx_ok - Function returns bit
  • nrf24_tx_ready - Function returns bit


nrf905.jal - JALLIB Library Documentation

nrf905.jal JALLIB LIBRARY

Title

nRF905 library for wireless communication.

Author

Rob Jansen, Copyright (c) 2020..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Libray for wireless transmission and reception using the nRF905.

Notes

The following pins must be defined by the main program before
including this library:
-) alias nrf905_spi_sck -- To sck of nRF905
-) alias nrf905_spi_sck_direction
-) alias nrf905_spi_sdi -- To MISO of nRF905
-) alias nrf905_spi_sdi_direction
-) alias nrf905_spi_sdo -- To MOSI of nRFF905
-) alias nrf905_spi_sdo_direction
-) alias nrf905_csn_pin -- To csn of nRF905
-) alias nrf905_csn_pin_direction
-) alias nrf905_txen_pin -- To txen of nRF905
-) alias nrf905_txen_pin_direction
-) alias nrf905_trx_ce_pin -- To (tx_)ce of nRF905
-) alias nrf905_trx_ce_pin_direction
Optional pins (see defines below):
-) alias nrf905_pwr_up_pin -- To pwr(_up) of nRF905
-) alias nrf905_pwr_up_pin_direction
-) alias nrf905_dr_pin -- To DR of nRF905. Pin is
-) alias nrf905_dr_pin_direction connected to the INT pin.
A receive buffer called 'nrf905_rx_buffer' is used for storage of
received data. The size of this buffer is defined as follows:
-) const byte NRF905_RX_BUFFER_SIZE = <your size>.
The buffer size must be equal or greater than the payload size used
for reception. If no buffer size is defined then the buffer will
have the size NRF905_MAX_PAYLOAD.
By default the SPI hardware is used. This library also implements
a software SPI interface for making pin assignments more flexible
or when using a PIC that has no hardware SPI interface.
In order to use this featur define the following:
-) const NRF905_SOFTWARE_SPI = TRUE
The power of the nRF905 can be controlled with a power pin. This
feature can be used by defining the following:
-) const NRF905_USE_PWR_PIN = TRUE
If not used, connect the PWR pin of the nRF905 to VCC. In this
case the pin definition nrf905_pwr_up_pin is not needed.
The operation of the nRF905 can be controlled via the external PIC
interrupt using the DR of the nRF905 pin. This feature can be
activated by defining the following:
-) const NRF905_USE_INTERRUPT = TRUE
If this feature is used, the new received data is immediately copied
to the nrf905_rx_buffer, giving the main program more time before
processing it. If this feature is not used the main program has to
check frequently if new data is received. In that case the pin
definition nrf905_dr_pin is not needed.
In addition, the following aliases and const must be defined:
-) alias nrf905_external_interrupt_enable is INTCON_INTE
-) alias nrf905_global_interrupt_enable is INTCON_GIE
-) alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
-) alias nrf905_external_interrupt_flag is INTCON_INTF
-) const nrf905_postive_interrupt_edge = TRUE
Some hardware related information:
-) The nRF905 operates at a supply voltage of 3.3 Volt.
When using the PIC on 5 Volt, use a bidirectional level shifter.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

General minimum and maximum definitions.

Sources

nRF905 product specification Revision 1.5 (April 2008)

Constants and Variables

NRF905_MIN_PAYLOAD - const byte = 1
NRF905_MAX_PAYLOAD - const byte = 32
NRF905_MAX_CHANNEL - const word = 511
NRF905_MAX_TX_ADDRESS - const byte = 4
NRF905_MAX_RX_ADDRESS - const byte = 4
NRF905_CRYSTAL_CLK_4MHZ - const byte = 0x00
NRF905_CRYSTAL_CLK_8MHZ - const byte = 0x01
NRF905_CRYSTAL_CLK_12MHZ - const byte = 0x02
NRF905_CRYSTAL_CLK_16MHZ - const byte = 0x03
NRF905_CRYSTAL_CLK_20MHZ - const byte = 0x04
NRF905_OUTPUT_CLK_4MHZ - const byte = 0x00
NRF905_OUTPUT_CLK_2MHZ - const byte = 0x01
NRF905_OUTPUT_CLK_1MHZ - const byte = 0x02
NRF905_OUTPUT_CLK_500KHZ - const byte = 0x03
NRF905_POWER_LEVEL_MIN - const byte = 0b000_0000 -- -10dBm
-10dBm
NRF905_POWER_LEVEL_LOW - const byte = 0b000_0100 -- -2dBm
-2dBm
NRF905_POWER_LEVEL_MED - const byte = 0b000_1000 -- +6dBm
+6dBm
NRF905_POWER_LEVEL_MAX - const byte = 0b000_1100 -- +10dBm
+10dBm
NRF905_RX_BUFFER_SIZE - const byte = NRF905_MAX_PAYLOAD

Routines

  • _nrf905_copy_data - Procedure
  • _nrf905_get_am_status - Function returns bit
  • _nrf905_get_dr_status - Function returns bit
  • _nrf905_get_status_register - Function returns byte
  • _nrf905_interrupt - Procedure
  • _nrf905_read_configuration_register - Function returns byte
  • _nrf905_write_configuration_register - Procedure
  • nrf905_data_available - Function returns bit
  • nrf905_disable_auto_retransmit - Procedure
  • nrf905_disable_crc_check - Procedure
  • nrf905_disable_output_clock - Procedure
  • nrf905_enable_auto_retransmit - Procedure
  • nrf905_enable_crc_check - Procedure
  • nrf905_enable_output_clock - Procedure
  • nrf905_get_data - Function returns bit
  • nrf905_init - Procedure
  • nrf905_on - Procedure
  • nrf905_power_down_device - Procedure
  • nrf905_power_up_device - Procedure
  • nrf905_power_up_rx - Procedure
  • nrf905_power_up_tx - Procedure
  • nrf905_print_configuration_register - Procedure
  • nrf905_print_status_register - Procedure
  • nrf905_send_data - Procedure
  • nrf905_set_crc_check_16_bit - Procedure
  • nrf905_set_crc_check_8_bit - Procedure
  • nrf905_set_crystal_clock - Procedure
  • nrf905_set_output_clock_frequency - Procedure
  • nrf905_set_power_level - Procedure
  • nrf905_set_rf_band_433 - Procedure
  • nrf905_set_rf_band_868_915 - Procedure
  • nrf905_set_rf_channel - Procedure
  • nrf905_set_rx_address - Procedure
  • nrf905_set_rx_address_width_1_byte - Procedure
  • nrf905_set_rx_address_width_4_byte - Procedure
  • nrf905_set_rx_low_power - Procedure
  • nrf905_set_rx_normal_power - Procedure
  • nrf905_set_rx_payload_width - Procedure
  • nrf905_set_tx_address - Procedure
  • nrf905_set_tx_address_width_1_byte - Procedure
  • nrf905_set_tx_address_width_4_byte - Procedure
  • nrf905_set_tx_payload_width - Procedure
  • nrf905_spi_exchange - Function returns byte
  • nrf905_standby - Procedure
  • nrf905_tx_ready - Function returns bit


nrf905_get_data - JALlib Procedures Help

nrf905_get_data JALLIB FUNCTION

Signature

function nrf905_get_data() return bit is

Description

Checks if data is available and if so copies the data to the nrf905_read_buffer
and returns TRUE when done.

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_init - JALlib Procedures Help

nrf905_init JALLIB PROCEDURE

Signature

procedure nrf905_init() is

Description

Initialize the SPI interface and the nRF905 module. The module is placed in
its default mode: Channel 108, 433 MHz band, -10 dBm power, normal power use,
no retransmit, tx and rx address width 4 bytes, maximum payload, output clock
500 kHz, output clock enabled, crystal clock 20 MHz, crc check enabled,
16-bit crc check used. After intialized the module is in standby mode.

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_power_up_device - JALlib Procedures Help

nrf905_power_up_device JALLIB PROCEDURE

Signature

procedure nrf905_power_up_device() is

Description

Power up the device. Only used when power pin is defined.

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_power_up_rx - JALlib Procedures Help

nrf905_power_up_rx JALLIB PROCEDURE

Signature

procedure nrf905_power_up_rx() is

Description

Power up the receiver

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_print_configuration_register - JALlib Procedures Help

nrf905_print_configuration_register JALLIB PROCEDURE

Signature

procedure nrf905_print_configuration_register() is

Description

No description available.

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_print_status_register - JALlib Procedures Help

nrf905_print_status_register JALLIB PROCEDURE

Signature

procedure nrf905_print_status_register() is

Description

No description available.

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_send_data - JALlib Procedures Help

nrf905_send_data JALLIB PROCEDURE

Signature

procedure nrf905_send_data(byte in data[], byte in nr_of_bytes) is

Description

Power up the transmitter and send the given data to the previously set TX
address. The transmitter remains powered up after completion.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • data[] - byte in
  • nr_of_bytes - byte in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_crystal_clock - JALlib Procedures Help

nrf905_set_crystal_clock JALLIB PROCEDURE

Signature

procedure nrf905_set_crystal_clock(byte in crystal_clock) is

Description

Set the crystal clock frequency.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • crystal_clock - byte in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_power_level - JALlib Procedures Help

nrf905_set_power_level JALLIB PROCEDURE

Signature

procedure nrf905_set_power_level(byte in power) is

Description

Set the power level of the transmitter. Use the defined power rate constants.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • power - byte in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_rf_channel - JALlib Procedures Help

nrf905_set_rf_channel JALLIB PROCEDURE

Signature

procedure nrf905_set_rf_channel(word in channel) is

Description

Set the RF channel. Channel is a 9-bit value. Some info on channels:
-) Channel 0 is 422.4MHz for the 433MHz band, each channel increments the
frequency by 100KHz, so channel 10 would be 423.4MHz
-) Channel 0 is 844.8MHz for the 868/915MHz band, each channel increments the
frequency by 200KHz, so channel 10 would be 846.8MHz
-) Max channel is 511 (473.5MHz / 947.0MHz)

Include

To use this procedure, include the library:

include nrf905

Parameters

  • channel - word in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_rx_address - JALlib Procedures Help

nrf905_set_rx_address JALLIB PROCEDURE

Signature

procedure nrf905_set_rx_address(dword in address) is

Description

Set the receiver address. Address can be 1 byte or 4 bytes.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • address - dword in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_rx_payload_width - JALlib Procedures Help

nrf905_set_rx_payload_width JALLIB PROCEDURE

Signature

procedure nrf905_set_rx_payload_width(byte in payload) is

Description

Set the receiver payload width.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • payload - byte in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_tx_address - JALlib Procedures Help

nrf905_set_tx_address JALLIB PROCEDURE

Signature

procedure nrf905_set_tx_address(dword in address) is

Description

Set the transmitter address. Address can be 1 byte or 4 bytes.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • address - dword in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_set_tx_payload_width - JALlib Procedures Help

nrf905_set_tx_payload_width JALLIB PROCEDURE

Signature

procedure nrf905_set_tx_payload_width(byte in payload) is

Description

Set the transmitter payload width.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • payload - byte in

Return Value

None

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_spi_exchange - JALlib Procedures Help

nrf905_spi_exchange JALLIB FUNCTION

Signature

function nrf905_spi_exchange(byte in data) return byte is

Description

SPI interface done in software using same the function name as hardware SPI.

Include

To use this procedure, include the library:

include nrf905

Parameters

  • data - byte in

Return Value

byte - Function return value

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


nrf905_tx_ready - JALlib Procedures Help

nrf905_tx_ready JALLIB FUNCTION

Signature

function nrf905_tx_ready() return bit is

Description

Check the status of the transmission and return TRUE when ready.

Include

To use this procedure, include the library:

include nrf905

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_nrf905.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the nRF905.
-- Author: Rob Jansen, Copyright (c) 2020..2024 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
--
-- Description: This program sends a message once every two seconds to two different
--              nRF905 devices and will print any received message from these
--              devices.
--
-- Notes:       See sample program 16f1823_nrf905.jal for the counter part of
--              this sample program (the receiver of the message sent).
--

include 16f1825

-- Variable reduce reduces both RAM and ROM for this sample program.
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- internal oscillator
pragma target PLLEN    DISABLED        -- PLL off
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     INTERNAL        -- Reset internal
OSCCON_SCS = 0                         -- select primary oscillator
OSCCON_IRCF = 0b1101                   -- 4 MHz
OSCCON_SPLLEN = FALSE                  -- software PLL off

-- Enable weak pull up for all pins.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
-- Take some time to stabilize.
_usec_delay(100_000)

-- For debugging purposes this constant can be defined.
-- const NRF905_DEBUG = TRUE

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- nRF905 pin definition.
alias nrf905_spi_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias nrf905_spi_sck_direction is pin_C0_direction -- To SCK of nRF905
alias nrf905_spi_sdi is pin_C1 -- Pin 9 for 14 pin DIP.
alias nrf905_spi_sdi_direction is pin_C1_direction -- To MISO of nRF905
alias nrf905_spi_sdo is pin_C2 -- Pin 8 for 14 pin DIP.
alias nrf905_spi_sdo_direction is pin_C2_direction -- To MOSI of nRFF905
alias nrf905_csn_pin is pin_C3 -- Pin 7 for 14 pin DIP.
alias nrf905_csn_pin_direction is pin_C3_direction -- To csn of nRF905
alias nrf905_txen_pin is pin_A5 -- Pin 2 for 14 pin DIP.
alias nrf905_txen_pin_direction is pin_A5_direction -- To txen of nRF905
alias nrf905_trx_ce_pin is pin_A4 -- Pin 3 for 14 pin DIP.
alias nrf905_trx_ce_pin_direction is pin_A4_direction  -- To (tx_)ce of nRF905

-- We use software SPI. If not defined, hardware SPI must be included with an alias.
const bit NRF905_SOFTWARE_SPI = TRUE
if !defined(NRF905_SOFTWARE_SPI) then
   -- Setup hardware SPI interface. Not the maximum speed.
   include spi_master_hw
   spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   alias nrf905_spi_exchange is spi_master_hw_exchange
end if

-- When using the power pin, define it here. If not used connect the power pin
-- of the module to VCC.
-- const NRF905_USE_PWR_PIN = TRUE
if defined(NRF905_USE_PWR_PIN) then
   alias nrf905_pwr_up_pin is pin_A1 -- Pin 12 for 14 pin DIP.
   alias nrf905_pwr_up_pin_direction is pin_A1_direction
end if

-- This program uses the interrupt way of receiving new data which gives the
-- main program more time before processing it.
-- const NRF905_USE_INTERRUPT = TRUE
if defined(NRF905_USE_INTERRUPT) then
   -- Aliases for the interrupts.
   alias nrf905_dr_pin is pin_A2 -- Pin 11 for 14 pin DIP, external interrupt.
   alias nrf905_dr_pin_direction is pin_A2_direction  -- To DR of nRF905
   alias nrf905_external_interrupt_enable is INTCON_INTE
   alias nrf905_global_interrupt_enable is INTCON_GIE
   alias nrf905_external_interrupt_edge is OPTION_REG_INTEDG
   alias nrf905_external_interrupt_flag is INTCON_INTF
   const nrf905_postive_interrupt_edge = TRUE
end if

-- nRF905 addresses. We use 4-bit addresses (default).
const dword NRF905_RX_ADDR_1 = 0x11223344  -- My address.
const dword NRF905_TX_ADDR_1 = 0x55667788  -- Address of device 1.
const dword NRF905_TX_ADDR_2 = 0xBBCCDDEE  -- Address of device 1.

-- We do not use the library default payload size (default is maximum of 32).
const byte NRF905_TX_PAYLOAD_SIZE = 25
const byte NRF905_RX_PAYLOAD_SIZE = 25
-- The RX buffer size must be equal to or bigger than the highest payload size.
const byte NRF905_RX_BUFFER_SIZE  = 25
include nrf905

-- Use my own RF channel (default is 108). Range from 0 .. NRF905_MAX_CHANNEL.
const word MY_CHANNEL = 50

-- Some text constants.
const byte start[] = "Test program for nRF905.\r\n"
const byte hello_1[] = "Hello World 1!"
const byte hello_2[] = "Hello World 2!"

-- Used variables.
var word timer
var byte counter, index
var byte device_to_send_to
var bit sending_data

-- Initialize the bRF905 module with the default values.
nrf905_init()
if defined(NRF905_USE_PWR_PIN) then
   nrf905_power_up_device()
end if
-- Set receiver address of this device.
nrf905_set_rx_address(NRF905_RX_ADDR_1)
-- Our module has a 16 MHz clock (init value is 20 MHz)
nrf905_set_crystal_clock(NRF905_CRYSTAL_CLK_16MHZ)
-- Set a different payload width for this program.
nrf905_set_rx_payload_width(NRF905_RX_PAYLOAD_SIZE)
nrf905_set_tx_payload_width(NRF905_TX_PAYLOAD_SIZE)
nrf905_set_power_level(NRF905_POWER_LEVEL_MIN)
nrf905_set_rf_channel(MY_CHANNEL)

-- Show welcome message on the screen.
print_string(serial_hw_data,start)
print_crlf(serial_hw_data)

timer = 0
sending_data = FALSE
device_to_send_to = 1

forever loop
   -- Loop timer 1 ms.
   _usec_delay(1_000)

   -- Send a message to one of the devices and alternate devices..
   timer = timer + 1
   -- Wait 1 second before sending the next message.
   if (timer >= 1_000) then
      print_crlf(serial_hw_data)
      if (device_to_send_to == 1)
      then
         -- Send to first device.
         print_string(serial_hw_data,"Sending data to device 1 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_1)
         nrf905_send_data(hello_1, count(hello_1))
         device_to_send_to = 2
      elsif (device_to_send_to == 2)
      then
         -- Send to second device.
         print_string(serial_hw_data,"Sending data to device 2 ... ")
         nrf905_set_tx_address(NRF905_TX_ADDR_2)
         nrf905_send_data(hello_2, count(hello_2))
         device_to_send_to = 1
      end if
      sending_data = TRUE
      timer = 0

      -- For debugging purposes.
      if defined(NRF905_DEBUG) then
         print_crlf(serial_hw_data)
         print_crlf(serial_hw_data)
         nrf905_print_status_register()
         print_crlf(serial_hw_data)
         nrf905_print_configuration_register()
      end if

   end if

   -- Print the transmission status and enable the receiver.
   if sending_data & nrf905_tx_ready() then
      -- Transmission done, check if successful.
      print_string(serial_hw_data,"Transmission Done! \r\n")
      print_string(serial_hw_data,"Enabling receiver ... \r\n")
      -- Enable receiver again.
      nrf905_power_up_rx()
      sending_data = FALSE
   end if

   -- Print the message from any of the 2 devices. Ignore the values 0x00 which
   -- can be added when the received message is shorter than the maximum payload.
   if nrf905_get_data() then
      print_crlf(serial_hw_data)
      print_string(serial_hw_data,"Receiving data: ")
      for NRF905_RX_PAYLOAD_SIZE using index loop
         if nrf905_rx_buffer[index] != 0x00 then
            serial_hw_data = nrf905_rx_buffer[index]
         end if
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: nrf905.jal


one_wire.jal - JALLIB Library Documentation

one_wire.jal JALLIB LIBRARY

Title

one wire JAL library

Author

Vasile Surducan, Copyright (c) 2009..2020, all rights reserved., Adapted-by: Jean Marchaudon, Joep Suijs, Oliver "Kiste" Seitz

Compiler

>=2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to interface with Dallas / Maxim one-wire-bus devices
--
Pin used for the 1-wire bus must be define these in your program
before including the library. E.g.:
alias d1w_bus is pin_c1
alias d1w_bus_direction is pin_c1_direction
Optional:
const d1w_bus_interrupt_safety_level= 0|1|2
Interrupt safety level 0 allows interrupts at any time, possibly corrupting
data transmission occasionally.
Level 1 prevents interrupts to occur while transmitting a bit, highly
reducing probability of transmission failure while only postponing interrupts
by less than 100us.
Level 2 prevents interrupts to occur while transmitting a byte and powering
up the bus. This prevents any interrupt interference but can postpone
interrupts by up to 1000us.

Notes

------------------------------------------------------

Routines

  • _d1w_read_bit - Procedure
  • _d1w_write_bit - Procedure
  • d1w_init - Procedure
  • d1w_present - Function returns bit
  • d1w_read_byte - Procedure
  • d1w_reset - Procedure
  • d1w_write_byte - Procedure


Operator Precedence - JAL Language Syntax Reference

Operator Precedence JALV2 SYNTAX

Generated by JAL Syntax Documentation System | Source: DITA


Operators, Casting, Expressions - JAL Language Syntax Reference

Operators, Casting, Expressions JALV2 SYNTAX

Description

Generated by JAL Syntax Documentation System | Source: DITA


Other Keywords - JAL Language Syntax Reference

Other Keywords JALV2 SYNTAX

Description

Generated by JAL Syntax Documentation System | Source: DITA


pata_hard_disk.jal - JALLIB Library Documentation

pata_hard_disk.jal JALLIB LIBRARY

Title

Hard disk library for communicating with parallel ata hard drives

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides functions for pata/ide hard disk drives.

Notes

- If you are not using Alternate Status, Digital Output or Drive Address registers
pins cs1 & cs0 can be saved by connecting these ide pins to cs0-high, cs1-low
at ide connector. normal operation does not require these pins. Set
"CONST BYTE PATA_HD_USE_CS0_CS1_PINS = TRUE" if you will be using
these registers
- You MUST write full sectors of 512 bytes.
- this lib does not do error checking
Pin-outs - PATA IDE 40 pin connector
Power connector - black ground, red +5v, yellow +12v
- 2.5" laptop drives do not need 12v
2,19,22,24,26,30,40 - connect direct to ground
1 - /reset, connect to switch (high 5v for normal operation, low resets drive)
28 - ALE, connect to -> 1k resistor -> 5v
39 - ACT, connect to -> LED -> 1k resistor -> 5v
21,27,20,29,31,32,34, leave not connected
3,5,7,9,11,13,15,17 - D0-D7, connect direct to pata_hd_data_low pins
18,16,14,12,10,8,6,4 - D8-D15, connect direct to pata_hd_data_high pins
23 - /IOW, connect direct to iowr -- see constant PATA_HD_NO_INVERTER
25 - /IOR, connect direct to pata_hd_iord -- see constant PATA_HD_NO_INVERTER
38 - /cs0, connect direct to pata_hd_cs0 (or gnd) -- see constant PATA_HD_NO_INVERTER & PATA_HD_USE_CS0_CS1_PINS
37 - /cs1, connect direct to pata_hd_cs1 (or 5v) -- see constant PATA_HD_NO_INVERTER & PATA_HD_USE_CS0_CS1_PINS
36 - A2, connect direct to pata_hd_a2
33 - A1, connect direct to pata_hd_a1
35 - A0, connect direct to pata_hd_a0
Watch for open drain pins on your pic, use pull-up resistors.

readable/writeable registers

Sources

"connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
IDE hardware reference & information document by alex t. ivopol
ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf

Constants and Variables

PATA_HD_WAIT_READ - const bit = 0 -- wait for sector buffer to fill it's contents with data from disk platters
wait for sector buffer to fill it's contents with data from disk platters
PATA_HD_WAIT_WRITE - const bit = 1 -- wait for sector buffer to empty it's contents to disk platters
wait for sector buffer to empty it's contents to disk platters
PATA_HD_READ - const bit = 0 -- wait for sector buffer to fill it's contents with data from disk platters
wait for sector buffer to fill it's contents with data from disk platters
PATA_HD_WRITE - const bit = 1 -- wait for sector buffer to empty it's contents to disk platters
wait for sector buffer to empty it's contents to disk platters
pata_hd_word_count - var byte = 0 -- counts words read from current sector, must be a byte
counts words read from current sector, must be a byte
pata_hd_sector_count - var byte = 0 -- counds sectors read, must be a byte.
counds sectors read, must be a byte.
pata_hd_sector_select - var dword = 0
pata_hd_byte_location - var bit = 0
pata_hd_last_operation - var bit
pata_hd_high_byte2 - var byte
pata_hd_high_byte - var byte
pata_hd_last_sector - var dword
pata_hd_sector_count2 - var byte = 0
pata_hd_prev_address - var dword = 0
pata_hd_current_address - var dword = 0xFF_FF_FF_FF

Routines

  • _pata_read_512 - Procedure
  • pata_hd_data_byte'get - Function returns byte
  • pata_hd_data_byte'put - Procedure
  • pata_hd_data_request - Procedure
  • pata_hd_delay_100ns - Procedure
  • pata_hd_drive_busy - Procedure
  • pata_hd_drive_ready - Procedure
  • pata_hd_go_to_sector - Procedure
  • pata_hd_init - Procedure
  • pata_hd_number_of_sectors'get - Function returns dword
  • pata_hd_print_drive_information - Procedure
  • pata_hd_print_sector - Procedure
  • pata_hd_print_sector_hex - Procedure
  • pata_hd_read_data - Procedure
  • pata_hd_read_data_byte - Procedure
  • pata_hd_read_pulse - Procedure
  • pata_hd_read_pulse_byte - Procedure
  • pata_hd_read_sector - Procedure
  • pata_hd_read_sector_address - Procedure
  • pata_hd_read_to_sector_end - Procedure
  • pata_hd_register_read - Procedure
  • pata_hd_register_write - Procedure
  • pata_hd_sector_buffer'get - Function returns byte
  • pata_hd_sector_buffer'put - Procedure
  • pata_hd_select_register - Procedure
  • pata_hd_set_address - Procedure
  • pata_hd_set_idle - Procedure
  • pata_hd_start_read - Procedure
  • pata_hd_start_write - Procedure
  • pata_hd_stop_read - Procedure
  • pata_hd_stop_write - Procedure
  • pata_hd_write_data - Procedure
  • pata_hd_write_data_byte - Procedure
  • pata_hd_write_pulse - Procedure
  • pata_hd_write_pulse_byte - Procedure
  • pata_hd_write_sector - Procedure
  • pata_hd_write_sector_address - Procedure
  • pata_hd_write_to_sector_end - Procedure


pata_hd_data_request - JALlib Procedures Help

pata_hd_data_request JALLIB PROCEDURE

Signature

procedure pata_hd_data_request(bit in read_write) is

Description

Wait for drive to be ready for a data transfer.
Sets data pins as inputs or outputs for next read or write.

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

  • read_write - bit in

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_init - JALlib Procedures Help

pata_hd_init JALLIB PROCEDURE

Signature

procedure pata_hd_init() is begin

Description

initialize startup settings

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_read_sector - JALlib Procedures Help

pata_hd_read_sector JALLIB PROCEDURE

Signature

procedure pata_hd_read_sector() is

Description

read one entire sector

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

None

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_read_sector_address - JALlib Procedures Help

pata_hd_read_sector_address JALLIB PROCEDURE

Signature

procedure pata_hd_read_sector_address(dword in address) is

Description

read one entire sector at address. no need for start_read/stop_read

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

  • address - dword in

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_register_write - JALlib Procedures Help

pata_hd_register_write JALLIB PROCEDURE

Signature

procedure pata_hd_register_write(byte in register, byte in low_byte) is begin

Description

Select a register and give it a command or data.

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

  • register - byte in
  • low_byte - byte in

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_start_read - JALlib Procedures Help

pata_hd_start_read JALLIB PROCEDURE

Signature

procedure pata_hd_start_read(dword in address) is

Description

Get drive ready for reading at specified address

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

  • address - dword in

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_start_write - JALlib Procedures Help

pata_hd_start_write JALLIB PROCEDURE

Signature

procedure pata_hd_start_write(dword in address) is

Description

Get drive ready for writing at specified address

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

  • address - dword in

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_stop_read - JALlib Procedures Help

pata_hd_stop_read JALLIB PROCEDURE

Signature

procedure pata_hd_stop_read() is

Description

Tell drive you are done reading

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

None

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_stop_write - JALlib Procedures Help

pata_hd_stop_write JALLIB PROCEDURE

Signature

procedure pata_hd_stop_write() is

Description

Tell drive you are done writing

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

None

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_write_sector - JALlib Procedures Help

pata_hd_write_sector JALLIB PROCEDURE

Signature

procedure pata_hd_write_sector() is

Description

Write one sector to the disk, requires start write/stop write.

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

None

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pata_hd_write_sector_address - JALlib Procedures Help

pata_hd_write_sector_address JALLIB PROCEDURE

Signature

procedure pata_hd_write_sector_address(dword in address) is

Description

write one entire sector at address. no need for start_read/stop_read

Include

To use this procedure, include the library:

include pata_hard_disk

Parameters

  • address - dword in

Return Value

None

Example

From sample file: 18f4620_pata_hard_disk.jal

-- Title: Hard disk library for communicating with parallel ata hard drives
--        with a 40 pin ide connector.
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides example usage for pata/ide hard disk drives.
--              includes examples for : spin up / spin down drive
--                                    : read sectors
--                                    : identify drive
--                                    : write sectors
--
-- Notes:
-- I also suggest you define pata_hd_reset pin connected to the hard disk reset pin.
-- You may use your ICSP /MCLR as reset if the voltage doesn't go over 5v.
-- Reset should be toggled once each time you start up your program.
--   alias     pata_hd_reset                 is pin_xx
--   alias     pata_hd_reset_direction       is pin_xx_direction
--
-- Sources:
-- "connecting ide drives by tilmann reh" - http://www.gaby.de/gide/IDE-TCJ.txt
-- IDE hardware reference & information document by alex t. ivopol
-- ATA Attachement with Packet Interface 6 - d1410r3-ATA-ATAPI-6.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- Send something to the serial port
separator()             -- send "----" via serial port
var byte start_string[] = "HARD DISK SAMPLE STARTED"
print_string(serial_hw_data,start_string)

-- variables for the sample
var word step1
var byte data

separator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 - read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
pata_hd_start_read(0)      -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = pata_hd_data_byte -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()        -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 - write to a sector 1 byte at a time
--------------------------------------------------------------------------------
pata_hd_start_write(20)    -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  pata_hd_data_byte = "A"  -- write 1 bytes of data
end loop
pata_hd_stop_write()       -- tell sd card you are done reading
--
-- read the data back
pata_hd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  data = pata_hd_data_byte       -- read 1 bytes of data
  serial_hw_write(data)    -- send byte via serial port
end loop
pata_hd_stop_read()             -- tell sd card you are done reading

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "B"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   pata_hd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      pata_hd_sector_buffer[step1] = "C"        -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   pata_hd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   pata_hd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   pata_hd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_hw_write (pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   pata_hd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "D"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     pata_hd_sector_buffer[step1] = "E"       -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   pata_hd_write_sector()                     -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   pata_hd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   pata_hd_start_read(20)
;   -- read the sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   pata_hd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_hw_write(pata_hd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   pata_hd_stop_read()                          -- tell sd card you are done reading
;
;
;   separator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay

-- ----------------------------------------------------------------------------
-- EXAMPLE #5 - spin up & spin down drive command
-- ----------------------------------------------------------------------------
for 2 loop
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_DOWN)    -- turn off motor
   _usec_delay(5_000_000) -- 5 sec delay
   pata_hd_register_write (PATA_HD_COMMAND_REG,PATA_HD_SPIN_UP)      -- turn on motor
   _usec_delay(5_000_000) -- 5 sec delay
end loop

separator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
-- ----------------------------------------------------------------------------
-- Example #6 - identify drive command (Read drive information)
-- size of drive, make, model, serial number, etc.
-- ----------------------------------------------------------------------------

-- send the identify drive command
pata_hd_register_write(PATA_HD_COMMAND_REG,PATA_HD_IDENTIFY_DRIVE)

-- check if drive is ready reading and set data ports as inputs
-- this MUST be used before reading since we did not use pata_hd_start_read
pata_hd_data_request(PATA_HD_WAIT_READ)

-- Read 512 bytes
for 512 loop                            -- 256 words, 512 bytes per sector
   data = pata_hd_data_byte
   serial_hw_data = data
end loop                                -- drive info high/low bytes are in reverse order

-------THE END!--------

Generated by JALlib CHM Help System | Source: pata_hard_disk.jal


pca9685.jal - JALLIB Library Documentation

pca9685.jal JALLIB LIBRARY

Title

Library for PCA9685 16 channel 12-bit PWM Controller

Author

Rob Jansen, Copyright (c) 2022..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for controlling the PCA9685 16 channel 12-bit PWM Controller.
The chip uses an IIC interface. In order to support multiple devices
connected to the same IIC bus, the IIC address is selectable.

Notes

This library supports the control of the PCA9685 via IIC.
The default is hardware IIC control but this can be overruled using
software IIC control by defining the following constant:
-) const PCA9685_SOFTWARE_IIC = TRUE
The default IIC address is defined by PCA9685_IIC_ADDRESS and can be
overruled by: const byte PCA9685_IIC_ADDRESS = <your iic address>.
During operation the IIC address can be changed dynamically to support
the control of multiple PCA9685 devices.
The following pins must be defined by the main program before
including this library. Common pins for using IIC:
-) alias pca9685_sck -- IIC to sck of rtc
-) alias pca9685_sck_direction
-) alias pca9685_sdo -- IIC to sda of rtc
-) alias pca9685_sdo_direction

=============================================================================
============================= PUBLIC CONSTANTS ==============================
=============================================================================

Define a default IIC address for the PCA9685 if not already defined. The
default address with A0 to A5 zero is 0x80, see figure 4 of the data sheet.

Sources

NXP Product data sheet, Rev. 4 — 16 April 2015

Constants and Variables

PCA9685_IIC_ADDRESS - const byte = 0x80
PCA9685_PWM_MIN_TIME - const word = 0
PCA9685_PWM_MAX_TIME - const word = 4095
PCA9685_PWM_FULL_TIME - const word = 0x1000
PCA9685_NR_OF_CHANNELS - const byte = 16
PCA9685_MIN_CHANNEL - const byte = 0
PCA9685_MAX_CHANNEL - const byte = PCA9685_NR_OF_CHANNELS - 1
PCA9685_ALL_CHANNEL - const byte = PCA9685_NR_OF_CHANNELS
PCA9685_PWM_MIN_FREQUENCY - const word = 24
PCA9685_PWM_MAX_FREQUENCY - const word = 1525
PCA9685_PWM_DEFAULT_FREQUENCY - const word = 200 -- Value after power up or reset.
Value after power up or reset.

Routines

  • __pca9685_read_register_data_on_off - Procedure
  • __pca9685_write_register_data_on_off - Procedure
  • _calculate_channel_register - Function returns byte
  • _pca9685_read_register - Function returns byte
  • _pca9685_write_register - Procedure
  • pca9685_disable_all_call_address - Procedure
  • pca9685_disable_sub_address_1 - Procedure
  • pca9685_disable_sub_address_2 - Procedure
  • pca9685_disable_sub_address_3 - Procedure
  • pca9685_enable_all_call_address - Procedure
  • pca9685_enable_sub_address_1 - Procedure
  • pca9685_enable_sub_address_2 - Procedure
  • pca9685_enable_sub_address_3 - Procedure
  • pca9685_get_all_call_address - Function returns byte
  • pca9685_get_channel_pwm_ratio - Procedure
  • pca9685_get_iic_address - Function returns byte
  • pca9685_get_oscillator_frequency - Function returns dword
  • pca9685_get_pwm_frequency - Function returns word
  • pca9685_get_sub_address_1 - Function returns byte
  • pca9685_get_sub_address_2 - Function returns byte
  • pca9685_get_sub_address_3 - Function returns byte
  • pca9685_init - Procedure
  • pca9685_reset - Procedure
  • pca9685_restart - Procedure
  • pca9685_select_external_oscillator - Procedure
  • pca9685_set_all_call_address - Procedure
  • pca9685_set_channel_off - Procedure
  • pca9685_set_channel_on - Procedure
  • pca9685_set_channel_pwm_percent - Procedure
  • pca9685_set_channel_pwm_ratio - Procedure
  • pca9685_set_iic_address - Procedure
  • pca9685_set_output_change_on_ack - Procedure
  • pca9685_set_output_change_on_stop - Procedure
  • pca9685_set_output_disable_high - Procedure
  • pca9685_set_output_disable_high_impedance - Procedure
  • pca9685_set_output_disable_low - Procedure
  • pca9685_set_output_inverted - Procedure
  • pca9685_set_output_not_inverted - Procedure
  • pca9685_set_output_open_drain - Procedure
  • pca9685_set_output_totempole - Procedure
  • pca9685_set_pwm_frequency - Procedure
  • pca9685_set_sub_address_1 - Procedure
  • pca9685_set_sub_address_2 - Procedure
  • pca9685_set_sub_address_3 - Procedure
  • pca9685_sleep - Procedure


pca9685_init - JALlib Procedures Help

pca9685_init JALLIB PROCEDURE

Signature

procedure pca9685_init() is

Description

Intialize the PCA9685 by initializing the IIC interface and restart the
device.
Note: When using a second PCA9685 device you need to set the IIC address
of that device first and call this init procedure again.

Include

To use this procedure, include the library:

include pca9685

Parameters

None

Return Value

None

Example

From sample file: 16f1825_pca9685_servo_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the PCA9685 16 channel 12-bit PWM Controller
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling two servos and one led with the PCA9685
--               16 channel 12-bit PWM controller. The following is done:
--               -) Servo 1 moves in small steps from left to right and returns left.
--               -) Servo 2 goes from left to right after a certain time and returns left.
--               -) The brightness of 2 leds increase and decreases in small steps.
--
-- Sources: NXP Product data sheet, Rev. 4 — 16 April 2015
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- We control the Output Enable of the PCA9685 which is active LOW.
alias pca9685_output_enable is pin_C2 -- Pin 8 for 14 pin DIP.
pin_C2_direction = output
pca9685_output_enable = HIGH -- Disabled.

-- Settings for the PCA9685 IIC and intialization.
alias pca9685_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias pca9685_sck_direction is pin_C0_direction
alias pca9685_sdo is pin_C1 -- Pin 9 for 14 pin DIP.
alias pca9685_sdo_direction is pin_C1_direction
-- If you want to use software IIC, define the following constant.
-- const PCA9685_SOFTWARE_IIC = TRUE

-- You can redefine the default IIC address. Only needed when not equal
-- to the default IIC address with address bits A0..A5 being zero which is 0x80.
-- For example a new default IIC address using A0 = 1 and A2..A5 = 0 gives:
-- const byte PCA9685_IIC_ADDRESS = 0x82 -- Bit 0 is the read/write bit.
include pca9685

-- Define the values for the servo. For the MG90S servo we use a PWM frequency
-- of 100 Hz instead of the default 50 Hz since we want to control a LED too.
-- Position 0 degrees angle equals a pulse of 1.5 ms, position +90 degrees
-- angle equals 2 ms and position -90 degrees angle equals 1 ms. We have
-- PCA9685_PWM_MAX_TIME + 1 (4096) steps in the PWM signal. The values for
-- 100 Hz (10 ms) then become as follows:
--   0 degrees : (1.5 / 10) * 4096 = 614. Middle position.
-- +90 degrees : (2 / 10)   * 4096 = 819. Right position.
-- -90 degrees : (1 / 10)   * 4096 = 410. Left position.
-- Note: The values below are after calibrating the positions.
const word SERVO_LEFT   = 200 -- 488 us
const word SERVO_MIDDLE = 630 -- 1.48 ms
const word SERVO_RIGHT  = 1030 -- 2.28 ms
-- Used PWM channels.
const byte PWM_CHANNEL_SERVO_1  = 15
const byte PWM_CHANNEL_SERVO_2  = 13
const byte PWM_CHANNEL_LED_1    = 11
const byte PWM_CHANNEL_LED_2    = 0

-- Some speed timing constants based on a 25 ms timer tick.
const word SERVO_2_SPEED   = 200
const word BRIGHTNESS_STEP = 40

-- Global variables.
var word timer_servo_2, position_servo_1, position_servo_2
var word brightness_led_1, brightness_led_2
var bit brightness_up_1, brightness_up_2

-- ------------------- The main program starts here -----------------
-- Initialize and start the PCA9685.
pca9685_init()

-- Choose 100 Hz as PWM frequency or 10 ms because of the leds.
pca9685_set_pwm_frequency(100)

-- Initialize the the servo variables.
position_servo_1 = SERVO_LEFT
position_servo_2 = SERVO_LEFT
timer_servo_2 = 0

-- Start led 1 at minimum brightness.
brightness_led_1 = 0
brightness_up_1 = TRUE

-- Start led 2 at maximim brightness.
brightness_led_2 = PCA9685_PWM_MAX_TIME
brightness_up_2 = FALSE

-- Switch all channels off.
pca9685_set_channel_off(PCA9685_ALL_CHANNEL)

-- Now we can enable the output.
pca9685_output_enable = LOW

forever  loop

   -- Main loop tick is 25 ms.
   _usec_delay(25_000)

   -- Increase the position of servo 1 in small steps.
   position_servo_1 = position_servo_1 + 1
   if (position_servo_1 >= SERVO_RIGHT) then
      position_servo_1 = SERVO_LEFT
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_1, 0, position_servo_1)

   -- Change the servo direction of servo 2 after a certain time.
   timer_servo_2 = timer_servo_2 + 1
   if (timer_servo_2 > SERVO_2_SPEED) then
      timer_servo_2 = 0
      -- Change to the opposite direction.
      if (position_servo_2 == SERVO_LEFT) then
         position_servo_2 = SERVO_RIGHT
      else
         position_servo_2 = SERVO_LEFT
      end if
      pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_2, 0, position_servo_2)
   end if

   -- Change brightness of LED 1.
   if brightness_up_1 then
      -- Going up.
      brightness_led_1 = brightness_led_1 + BRIGHTNESS_STEP
      if (brightness_led_1 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_1 = PCA9685_PWM_MAX_TIME
         brightness_up_1 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_1 >= BRIGHTNESS_STEP) then
         brightness_led_1 = brightness_led_1 - BRIGHTNESS_STEP
      else
         brightness_led_1 = 0
         brightness_up_1 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_1, 0, brightness_led_1)

   -- Change brightness of LED 2.
   if brightness_up_2 then
      -- Going up.
      brightness_led_2 = brightness_led_2 + BRIGHTNESS_STEP
      if (brightness_led_2 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_2 = PCA9685_PWM_MAX_TIME
         brightness_up_2 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_2 >= BRIGHTNESS_STEP) then
         brightness_led_2 = brightness_led_2 - BRIGHTNESS_STEP
      else
         brightness_led_2 = 0
         brightness_up_2 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_2, 0, brightness_led_2)

end loop

Generated by JALlib CHM Help System | Source: pca9685.jal


pca9685_set_channel_off - JALlib Procedures Help

pca9685_set_channel_off JALLIB PROCEDURE

Signature

procedure pca9685_set_channel_off(byte in channel) is

Description

Set the given channel output to OFF. The given channel must be in range
PCA9685_MIN_CHANNEL to PCA9685_MAX_CHANNEL. If the given channel equals
PCA9685_ALL_CHANNEL then all channels are set to OFF.

Include

To use this procedure, include the library:

include pca9685

Parameters

  • channel - byte in

Return Value

None

Example

From sample file: 16f1825_pca9685_servo_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the PCA9685 16 channel 12-bit PWM Controller
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling two servos and one led with the PCA9685
--               16 channel 12-bit PWM controller. The following is done:
--               -) Servo 1 moves in small steps from left to right and returns left.
--               -) Servo 2 goes from left to right after a certain time and returns left.
--               -) The brightness of 2 leds increase and decreases in small steps.
--
-- Sources: NXP Product data sheet, Rev. 4 — 16 April 2015
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- We control the Output Enable of the PCA9685 which is active LOW.
alias pca9685_output_enable is pin_C2 -- Pin 8 for 14 pin DIP.
pin_C2_direction = output
pca9685_output_enable = HIGH -- Disabled.

-- Settings for the PCA9685 IIC and intialization.
alias pca9685_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias pca9685_sck_direction is pin_C0_direction
alias pca9685_sdo is pin_C1 -- Pin 9 for 14 pin DIP.
alias pca9685_sdo_direction is pin_C1_direction
-- If you want to use software IIC, define the following constant.
-- const PCA9685_SOFTWARE_IIC = TRUE

-- You can redefine the default IIC address. Only needed when not equal
-- to the default IIC address with address bits A0..A5 being zero which is 0x80.
-- For example a new default IIC address using A0 = 1 and A2..A5 = 0 gives:
-- const byte PCA9685_IIC_ADDRESS = 0x82 -- Bit 0 is the read/write bit.
include pca9685

-- Define the values for the servo. For the MG90S servo we use a PWM frequency
-- of 100 Hz instead of the default 50 Hz since we want to control a LED too.
-- Position 0 degrees angle equals a pulse of 1.5 ms, position +90 degrees
-- angle equals 2 ms and position -90 degrees angle equals 1 ms. We have
-- PCA9685_PWM_MAX_TIME + 1 (4096) steps in the PWM signal. The values for
-- 100 Hz (10 ms) then become as follows:
--   0 degrees : (1.5 / 10) * 4096 = 614. Middle position.
-- +90 degrees : (2 / 10)   * 4096 = 819. Right position.
-- -90 degrees : (1 / 10)   * 4096 = 410. Left position.
-- Note: The values below are after calibrating the positions.
const word SERVO_LEFT   = 200 -- 488 us
const word SERVO_MIDDLE = 630 -- 1.48 ms
const word SERVO_RIGHT  = 1030 -- 2.28 ms
-- Used PWM channels.
const byte PWM_CHANNEL_SERVO_1  = 15
const byte PWM_CHANNEL_SERVO_2  = 13
const byte PWM_CHANNEL_LED_1    = 11
const byte PWM_CHANNEL_LED_2    = 0

-- Some speed timing constants based on a 25 ms timer tick.
const word SERVO_2_SPEED   = 200
const word BRIGHTNESS_STEP = 40

-- Global variables.
var word timer_servo_2, position_servo_1, position_servo_2
var word brightness_led_1, brightness_led_2
var bit brightness_up_1, brightness_up_2

-- ------------------- The main program starts here -----------------
-- Initialize and start the PCA9685.
pca9685_init()

-- Choose 100 Hz as PWM frequency or 10 ms because of the leds.
pca9685_set_pwm_frequency(100)

-- Initialize the the servo variables.
position_servo_1 = SERVO_LEFT
position_servo_2 = SERVO_LEFT
timer_servo_2 = 0

-- Start led 1 at minimum brightness.
brightness_led_1 = 0
brightness_up_1 = TRUE

-- Start led 2 at maximim brightness.
brightness_led_2 = PCA9685_PWM_MAX_TIME
brightness_up_2 = FALSE

-- Switch all channels off.
pca9685_set_channel_off(PCA9685_ALL_CHANNEL)

-- Now we can enable the output.
pca9685_output_enable = LOW

forever  loop

   -- Main loop tick is 25 ms.
   _usec_delay(25_000)

   -- Increase the position of servo 1 in small steps.
   position_servo_1 = position_servo_1 + 1
   if (position_servo_1 >= SERVO_RIGHT) then
      position_servo_1 = SERVO_LEFT
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_1, 0, position_servo_1)

   -- Change the servo direction of servo 2 after a certain time.
   timer_servo_2 = timer_servo_2 + 1
   if (timer_servo_2 > SERVO_2_SPEED) then
      timer_servo_2 = 0
      -- Change to the opposite direction.
      if (position_servo_2 == SERVO_LEFT) then
         position_servo_2 = SERVO_RIGHT
      else
         position_servo_2 = SERVO_LEFT
      end if
      pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_2, 0, position_servo_2)
   end if

   -- Change brightness of LED 1.
   if brightness_up_1 then
      -- Going up.
      brightness_led_1 = brightness_led_1 + BRIGHTNESS_STEP
      if (brightness_led_1 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_1 = PCA9685_PWM_MAX_TIME
         brightness_up_1 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_1 >= BRIGHTNESS_STEP) then
         brightness_led_1 = brightness_led_1 - BRIGHTNESS_STEP
      else
         brightness_led_1 = 0
         brightness_up_1 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_1, 0, brightness_led_1)

   -- Change brightness of LED 2.
   if brightness_up_2 then
      -- Going up.
      brightness_led_2 = brightness_led_2 + BRIGHTNESS_STEP
      if (brightness_led_2 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_2 = PCA9685_PWM_MAX_TIME
         brightness_up_2 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_2 >= BRIGHTNESS_STEP) then
         brightness_led_2 = brightness_led_2 - BRIGHTNESS_STEP
      else
         brightness_led_2 = 0
         brightness_up_2 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_2, 0, brightness_led_2)

end loop

Generated by JALlib CHM Help System | Source: pca9685.jal


pca9685_set_channel_pwm_percent - JALlib Procedures Help

pca9685_set_channel_pwm_percent JALLIB PROCEDURE

Signature

procedure pca9685_set_channel_pwm_percent(byte in channel, byte in percent) is

Description

Set the channel PWM duty cycle in % of the on time where 0% is off and 100%
is on. The given channel must be in range PCA9685_MIN_CHANNEL to
PCA9685_MAX_CHANNEL. If the given channel equals PCA9685_ALL_CHANNEL then
all channels will be set with the given percentage.

Include

To use this procedure, include the library:

include pca9685

Parameters

  • channel - byte in
  • percent - byte in

Return Value

None

Example

From sample file: 16f1825_pca9685_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the PCA9685 16 channel 12-bit PWM Controller
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling leds with the PCA9685 16 channel
--              12-bit PWM controller. It will increase the brightness of the leds
--              on all channels.
--
-- Sources: NXP Product data sheet, Rev. 4 — 16 April 2015
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- We control the Output Enable of the PCA9685 which is active LOW.
alias pca9685_output_enable is pin_C2 -- Pin 8 for 14 pin DIP.
pin_C2_direction = output
pca9685_output_enable = HIGH -- Disabled.

-- Settings for the PCA9685 IIC and intialization.
alias pca9685_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias pca9685_sck_direction is pin_C0_direction
alias pca9685_sdo is pin_C1 -- Pin 9 for 14 pin DIP.
alias pca9685_sdo_direction is pin_C1_direction
-- If you want to use software IIC, define the following constant.
-- const PCA9685_SOFTWARE_IIC = TRUE

-- You can redefine the default IIC address. Only needed when not equal
-- to the default IIC address with address bits A0..A5 being zero which is 0x80.
-- For example a new default IIC address using A0 = 1 and A2..A5 = 0 gives:
-- const byte PCA9685_IIC_ADDRESS = 0x82 -- Bit 0 is the read/write bit.
include pca9685

var word off_time
var byte pwm_percentage, pwm_channel

 -- Wait 1 seconds.
procedure wait_1s() is
   _usec_delay(1_000_000)
end procedure

-- ------------------- The main program starts here -----------------

-- Initialize and start the PCA9685.
pca9685_init()

-- Choose 100 Hz as PWM frequency, the default is 200 Hz.
pca9685_set_pwm_frequency(100)

-- Switch all channels off.
pca9685_set_channel_off(PCA9685_ALL_CHANNEL)

-- Now we can enable the output.
pca9685_output_enable = LOW

forever loop

   -- Go through all channels and change brightness from 0% to 100%.
   for PCA9685_NR_OF_CHANNELS using pwm_channel loop
      for 100 using pwm_percentage loop
         pca9685_set_channel_pwm_percent(pwm_channel, pwm_percentage)
         _usec_delay(5_000)
      end loop
   end loop

   wait_1s()
   -- Switch them all off.
   for PCA9685_NR_OF_CHANNELS using pwm_channel loop
      pca9685_set_channel_off(pwm_channel)
   end loop
   wait_1s()

   -- Now do the same using the ratio, this gives a higher resoluion since
   -- it uses 4069 steps (0 .. PCA9685_PWM_MAX_TIME).
   for PCA9685_NR_OF_CHANNELS using pwm_channel loop
      for (PCA9685_PWM_MAX_TIME + 1) using off_time loop
         -- We always start the on-time a the start of a new cycle at
         -- PCA9685_PWM_MIN_TIME. This is not mandatory.
         pca9685_set_channel_pwm_ratio(pwm_channel, PCA9685_PWM_MIN_TIME, off_time)
         _usec_delay(100)
      end loop
   end loop

   wait_1s()
   -- Switch them all off.
   for PCA9685_NR_OF_CHANNELS using pwm_channel loop
      pca9685_set_channel_off(pwm_channel)
   end loop
   wait_1s()

end loop

Generated by JALlib CHM Help System | Source: pca9685.jal


pca9685_set_channel_pwm_ratio - JALlib Procedures Help

pca9685_set_channel_pwm_ratio JALLIB PROCEDURE

Signature

procedure pca9685_set_channel_pwm_ratio(byte in channel, word in on_time,

Description

Set the channel PWM duty cycle ratio by setting the ON time and OFF time.
-) The on_time is the moment between 0 and PCA9685_PWM_MAX_TIME where the
the output it turned ON.
-) The off_time is the moment between 0 and PCA9685_PWM_MAX_TIME where the
the output it turned OFF.
This gives maximum flexibility in defining the PWM delay and PWM duty cycle.
The given channel must be in range PCA9685_MIN_CHANNEL to PCA9685_MAX_CHANNEL.
If the given channel equals PCA9685_ALL_CHANNEL then all channels will be
set with the given PWM duty cycle ratio.

Include

To use this procedure, include the library:

include pca9685

Parameters

None

Return Value

None

Example

From sample file: 16f1825_pca9685_servo_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the PCA9685 16 channel 12-bit PWM Controller
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling two servos and one led with the PCA9685
--               16 channel 12-bit PWM controller. The following is done:
--               -) Servo 1 moves in small steps from left to right and returns left.
--               -) Servo 2 goes from left to right after a certain time and returns left.
--               -) The brightness of 2 leds increase and decreases in small steps.
--
-- Sources: NXP Product data sheet, Rev. 4 — 16 April 2015
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- We control the Output Enable of the PCA9685 which is active LOW.
alias pca9685_output_enable is pin_C2 -- Pin 8 for 14 pin DIP.
pin_C2_direction = output
pca9685_output_enable = HIGH -- Disabled.

-- Settings for the PCA9685 IIC and intialization.
alias pca9685_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias pca9685_sck_direction is pin_C0_direction
alias pca9685_sdo is pin_C1 -- Pin 9 for 14 pin DIP.
alias pca9685_sdo_direction is pin_C1_direction
-- If you want to use software IIC, define the following constant.
-- const PCA9685_SOFTWARE_IIC = TRUE

-- You can redefine the default IIC address. Only needed when not equal
-- to the default IIC address with address bits A0..A5 being zero which is 0x80.
-- For example a new default IIC address using A0 = 1 and A2..A5 = 0 gives:
-- const byte PCA9685_IIC_ADDRESS = 0x82 -- Bit 0 is the read/write bit.
include pca9685

-- Define the values for the servo. For the MG90S servo we use a PWM frequency
-- of 100 Hz instead of the default 50 Hz since we want to control a LED too.
-- Position 0 degrees angle equals a pulse of 1.5 ms, position +90 degrees
-- angle equals 2 ms and position -90 degrees angle equals 1 ms. We have
-- PCA9685_PWM_MAX_TIME + 1 (4096) steps in the PWM signal. The values for
-- 100 Hz (10 ms) then become as follows:
--   0 degrees : (1.5 / 10) * 4096 = 614. Middle position.
-- +90 degrees : (2 / 10)   * 4096 = 819. Right position.
-- -90 degrees : (1 / 10)   * 4096 = 410. Left position.
-- Note: The values below are after calibrating the positions.
const word SERVO_LEFT   = 200 -- 488 us
const word SERVO_MIDDLE = 630 -- 1.48 ms
const word SERVO_RIGHT  = 1030 -- 2.28 ms
-- Used PWM channels.
const byte PWM_CHANNEL_SERVO_1  = 15
const byte PWM_CHANNEL_SERVO_2  = 13
const byte PWM_CHANNEL_LED_1    = 11
const byte PWM_CHANNEL_LED_2    = 0

-- Some speed timing constants based on a 25 ms timer tick.
const word SERVO_2_SPEED   = 200
const word BRIGHTNESS_STEP = 40

-- Global variables.
var word timer_servo_2, position_servo_1, position_servo_2
var word brightness_led_1, brightness_led_2
var bit brightness_up_1, brightness_up_2

-- ------------------- The main program starts here -----------------
-- Initialize and start the PCA9685.
pca9685_init()

-- Choose 100 Hz as PWM frequency or 10 ms because of the leds.
pca9685_set_pwm_frequency(100)

-- Initialize the the servo variables.
position_servo_1 = SERVO_LEFT
position_servo_2 = SERVO_LEFT
timer_servo_2 = 0

-- Start led 1 at minimum brightness.
brightness_led_1 = 0
brightness_up_1 = TRUE

-- Start led 2 at maximim brightness.
brightness_led_2 = PCA9685_PWM_MAX_TIME
brightness_up_2 = FALSE

-- Switch all channels off.
pca9685_set_channel_off(PCA9685_ALL_CHANNEL)

-- Now we can enable the output.
pca9685_output_enable = LOW

forever  loop

   -- Main loop tick is 25 ms.
   _usec_delay(25_000)

   -- Increase the position of servo 1 in small steps.
   position_servo_1 = position_servo_1 + 1
   if (position_servo_1 >= SERVO_RIGHT) then
      position_servo_1 = SERVO_LEFT
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_1, 0, position_servo_1)

   -- Change the servo direction of servo 2 after a certain time.
   timer_servo_2 = timer_servo_2 + 1
   if (timer_servo_2 > SERVO_2_SPEED) then
      timer_servo_2 = 0
      -- Change to the opposite direction.
      if (position_servo_2 == SERVO_LEFT) then
         position_servo_2 = SERVO_RIGHT
      else
         position_servo_2 = SERVO_LEFT
      end if
      pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_2, 0, position_servo_2)
   end if

   -- Change brightness of LED 1.
   if brightness_up_1 then
      -- Going up.
      brightness_led_1 = brightness_led_1 + BRIGHTNESS_STEP
      if (brightness_led_1 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_1 = PCA9685_PWM_MAX_TIME
         brightness_up_1 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_1 >= BRIGHTNESS_STEP) then
         brightness_led_1 = brightness_led_1 - BRIGHTNESS_STEP
      else
         brightness_led_1 = 0
         brightness_up_1 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_1, 0, brightness_led_1)

   -- Change brightness of LED 2.
   if brightness_up_2 then
      -- Going up.
      brightness_led_2 = brightness_led_2 + BRIGHTNESS_STEP
      if (brightness_led_2 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_2 = PCA9685_PWM_MAX_TIME
         brightness_up_2 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_2 >= BRIGHTNESS_STEP) then
         brightness_led_2 = brightness_led_2 - BRIGHTNESS_STEP
      else
         brightness_led_2 = 0
         brightness_up_2 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_2, 0, brightness_led_2)

end loop

Generated by JALlib CHM Help System | Source: pca9685.jal


pca9685_set_pwm_frequency - JALlib Procedures Help

pca9685_set_pwm_frequency JALLIB PROCEDURE

Signature

procedure pca9685_set_pwm_frequency(word in frequency) is

Description

Set the PWM frequency. The frequency is given in Hz and must be
>= PCA9685_PWM_MIN_FREQUENCY and <= PCA9685_PWM_MAX_FREQUENCY when using
an oscillator frequency of 25 MHz (default internal oscillator frequency).

Include

To use this procedure, include the library:

include pca9685

Parameters

  • frequency - word in

Return Value

None

Example

From sample file: 16f1825_pca9685_servo_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the PCA9685 16 channel 12-bit PWM Controller
-- Author: Rob Jansen, Copyright (c) 2022..2022, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling two servos and one led with the PCA9685
--               16 channel 12-bit PWM controller. The following is done:
--               -) Servo 1 moves in small steps from left to right and returns left.
--               -) Servo 2 goes from left to right after a certain time and returns left.
--               -) The brightness of 2 leds increase and decreases in small steps.
--
-- Sources: NXP Product data sheet, Rev. 4 — 16 April 2015
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- We control the Output Enable of the PCA9685 which is active LOW.
alias pca9685_output_enable is pin_C2 -- Pin 8 for 14 pin DIP.
pin_C2_direction = output
pca9685_output_enable = HIGH -- Disabled.

-- Settings for the PCA9685 IIC and intialization.
alias pca9685_sck is pin_C0 -- Pin 10 for 14 pin DIP
alias pca9685_sck_direction is pin_C0_direction
alias pca9685_sdo is pin_C1 -- Pin 9 for 14 pin DIP.
alias pca9685_sdo_direction is pin_C1_direction
-- If you want to use software IIC, define the following constant.
-- const PCA9685_SOFTWARE_IIC = TRUE

-- You can redefine the default IIC address. Only needed when not equal
-- to the default IIC address with address bits A0..A5 being zero which is 0x80.
-- For example a new default IIC address using A0 = 1 and A2..A5 = 0 gives:
-- const byte PCA9685_IIC_ADDRESS = 0x82 -- Bit 0 is the read/write bit.
include pca9685

-- Define the values for the servo. For the MG90S servo we use a PWM frequency
-- of 100 Hz instead of the default 50 Hz since we want to control a LED too.
-- Position 0 degrees angle equals a pulse of 1.5 ms, position +90 degrees
-- angle equals 2 ms and position -90 degrees angle equals 1 ms. We have
-- PCA9685_PWM_MAX_TIME + 1 (4096) steps in the PWM signal. The values for
-- 100 Hz (10 ms) then become as follows:
--   0 degrees : (1.5 / 10) * 4096 = 614. Middle position.
-- +90 degrees : (2 / 10)   * 4096 = 819. Right position.
-- -90 degrees : (1 / 10)   * 4096 = 410. Left position.
-- Note: The values below are after calibrating the positions.
const word SERVO_LEFT   = 200 -- 488 us
const word SERVO_MIDDLE = 630 -- 1.48 ms
const word SERVO_RIGHT  = 1030 -- 2.28 ms
-- Used PWM channels.
const byte PWM_CHANNEL_SERVO_1  = 15
const byte PWM_CHANNEL_SERVO_2  = 13
const byte PWM_CHANNEL_LED_1    = 11
const byte PWM_CHANNEL_LED_2    = 0

-- Some speed timing constants based on a 25 ms timer tick.
const word SERVO_2_SPEED   = 200
const word BRIGHTNESS_STEP = 40

-- Global variables.
var word timer_servo_2, position_servo_1, position_servo_2
var word brightness_led_1, brightness_led_2
var bit brightness_up_1, brightness_up_2

-- ------------------- The main program starts here -----------------
-- Initialize and start the PCA9685.
pca9685_init()

-- Choose 100 Hz as PWM frequency or 10 ms because of the leds.
pca9685_set_pwm_frequency(100)

-- Initialize the the servo variables.
position_servo_1 = SERVO_LEFT
position_servo_2 = SERVO_LEFT
timer_servo_2 = 0

-- Start led 1 at minimum brightness.
brightness_led_1 = 0
brightness_up_1 = TRUE

-- Start led 2 at maximim brightness.
brightness_led_2 = PCA9685_PWM_MAX_TIME
brightness_up_2 = FALSE

-- Switch all channels off.
pca9685_set_channel_off(PCA9685_ALL_CHANNEL)

-- Now we can enable the output.
pca9685_output_enable = LOW

forever  loop

   -- Main loop tick is 25 ms.
   _usec_delay(25_000)

   -- Increase the position of servo 1 in small steps.
   position_servo_1 = position_servo_1 + 1
   if (position_servo_1 >= SERVO_RIGHT) then
      position_servo_1 = SERVO_LEFT
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_1, 0, position_servo_1)

   -- Change the servo direction of servo 2 after a certain time.
   timer_servo_2 = timer_servo_2 + 1
   if (timer_servo_2 > SERVO_2_SPEED) then
      timer_servo_2 = 0
      -- Change to the opposite direction.
      if (position_servo_2 == SERVO_LEFT) then
         position_servo_2 = SERVO_RIGHT
      else
         position_servo_2 = SERVO_LEFT
      end if
      pca9685_set_channel_pwm_ratio(PWM_CHANNEL_SERVO_2, 0, position_servo_2)
   end if

   -- Change brightness of LED 1.
   if brightness_up_1 then
      -- Going up.
      brightness_led_1 = brightness_led_1 + BRIGHTNESS_STEP
      if (brightness_led_1 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_1 = PCA9685_PWM_MAX_TIME
         brightness_up_1 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_1 >= BRIGHTNESS_STEP) then
         brightness_led_1 = brightness_led_1 - BRIGHTNESS_STEP
      else
         brightness_led_1 = 0
         brightness_up_1 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_1, 0, brightness_led_1)

   -- Change brightness of LED 2.
   if brightness_up_2 then
      -- Going up.
      brightness_led_2 = brightness_led_2 + BRIGHTNESS_STEP
      if (brightness_led_2 >= PCA9685_PWM_MAX_TIME) then
         brightness_led_2 = PCA9685_PWM_MAX_TIME
         brightness_up_2 = FALSE
      end if
   else
      -- Going down.
      if (brightness_led_2 >= BRIGHTNESS_STEP) then
         brightness_led_2 = brightness_led_2 - BRIGHTNESS_STEP
      else
         brightness_led_2 = 0
         brightness_up_2 = TRUE
      end if
   end if
   pca9685_set_channel_pwm_ratio(PWM_CHANNEL_LED_2, 0, brightness_led_2)

end loop

Generated by JALlib CHM Help System | Source: pca9685.jal


pcf8563_register_write - JALlib Procedures Help

pcf8563_register_write JALLIB PROCEDURE

Signature

procedure pcf8563_register_write(byte in ic_address, byte in reg, byte in data) is

Description

Programme to read and control the PCF8563 real time IC
IC address is 0xA2
PCF8563 read sequence
1. Send a START condition and the slave address for write (A2h).
2. Set the address pointer to 2 (VL_seconds) by sending 02h.
3. Send a RESTART condition or STOP followed by START.
4. Send the slave address for read (A3h).
5. Read VL_seconds. 02
6. Read Minutes. 03
7. Read Hours. 04
8. Read Days. 05
9. Read Weekdays. 06
10. Read Century_months. 07
11. Read Years. 08
12. Send a STOP condition.

Include

To use this procedure, include the library:

include rtc_pcf8563

Parameters

  • ic_address - byte in
  • reg - byte in
  • data - byte in

Return Value

None

Example

From sample file: 16f877a_rtc_pcf8563.jal

-- ------------------------------------------------------
-- Title: Example program for RTC PCF8563.jal
--
-- Author: Andy Brooker, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by: (Joep Suijs)
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Example program for RTC PCF8563.jal
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--

-- chip setup
include 16f877a

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init()
include print
include format
include delay

;Hardware setup.
;First you have to setup the i2c bus hardware.
;The first thing to concider is if you can and want to use the MSSP to handle
;i2c (i2c hardware) or handle i2c in software.
;The first option - i2c hardware - is possible for most (but not all) PICs with MSSP.
;The advantage is that this option is generally faster then software i2c.
;If you choose i2c hardware, you will use the pre-defined i2c clock and i2c data pins. (scl and sda).
;With i2c in software, pick any free io pin for i2c clock and i2c data.
;
;Now you have choosen the pins, you need to setup the hardware.
;Connect clock, data and ground from the PIC to the i2c slave, place pull-up resistors
;(e.g. 1k5) from both clock and data to the pic power supply and power the slave device.
;For more details on this, check the i2c slave datasheet or look on the Internet.
;
;Software setup
;Now you have the hardware ready, you need to configure the software.
;
;First, define the pins used, for example on an 16F877a:

var volatile bit i2c_scl is pin_c3
var volatile bit i2c_scl_direction is pin_c3_direction
var volatile bit i2c_sda is pin_c4
var volatile bit i2c_sda_direction is pin_c4_direction

;Second, define the next two constants:
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true ; i2c levels (not SMB)

;And now you can include the 'level0' i2c library.
;This is the library that creates the i2c signals and comes in two flavors:

;include i2c_software
;i2c_initialize()

;or

include i2c_hardware
i2c_initialize()
;Both libraries have the same interface to send and receive bytes.

pin_d4_direction=output
alias led is pin_d4

pin_c0_direction=input
pin_c1_direction=input
pin_c2_direction=input

alias up is pin_c0
alias set is pin_c1
alias down is pin_c2

led = on
delay_100ms(50)
led = off

const byte str1[] = "Clock running OK"      -- define strings
const byte time[] = "Set Time?"
const byte date[] = "Set Day?"

const byte weekday0[] = "Sunday"    ; 0 0 0
const byte weekday1[] = "Monday"    ; 0 0 1
const byte weekday2[] = "Tuesday"   ; 0 1 0
const byte weekday3[] = "Wednesday" ; 0 1 1
const byte weekday4[] = "Thursday"  ; 1 0 0
const byte weekday5[] = "Friday"    ; 1 0 1
const byte weekday6[] = "Saturday"  ; 1 1 1

const byte month1[] = "January"  ; 0 0 0 0 1
const byte month2[] = "February" ; 0 0 0 1 0
const byte month3[] = "March"    ; 0 0 0 1 1
const byte month4[] = "April"    ; 0 0 1 0 0
const byte month5[] = "May"      ; 0 0 1 0 1
const byte month6[] = "June"     ; 0 0 1 1 0
const byte month7[] = "July"     ; 0 0 1 1 1
const byte month8[] = "August"   ; 0 1 0 0 0
const byte month9[] = "September"; 0 1 0 0 1
const byte month10[] = "October" ; 1 0 0 0 0
const byte month11[] = "November"; 1 0 0 0 1
const byte month12[] = "December"; 1 0 0 1 0

const byte extn1[] = "st"
const byte extn2[] = "nd"
const byte extn3[] = "rd"
const byte extn4[] = "th"

var byte i, d1, sec, min, hour, day, weekday, month, year, old_years
var byte char, char1, number_char
var byte extn[2]
var byte month_name[9]
var bit r, fail
var byte old_set

const byte pcf8563_address = 0xA2
const byte years = 20
include rtc_pcf8563

procedure display_weekday() is

   if weekday == 0 then print_string(serial_hw_data,weekday0) end if
   if weekday == 1 then print_string(serial_hw_data,weekday1) end if
   if weekday == 2 then print_string(serial_hw_data,weekday2) end if
   if weekday == 3 then print_string(serial_hw_data,weekday3) end if
   if weekday == 4 then print_string(serial_hw_data,weekday4) end if
   if weekday == 5 then print_string(serial_hw_data,weekday5) end if
   if weekday == 6 then print_string(serial_hw_data,weekday6) end if
   serial_hw_data = " "

end procedure

procedure display_day_of_month() is
   print_byte_dec(serial_hw_data,day)
   extn = extn4
   if day == 1 then extn = extn1 end if
   if day == 21 then extn = extn1 end if
   if day == 31 then extn = extn1 end if
   if day == 2 then extn = extn2 end if
   if day == 22 then extn = extn2 end if
   if day == 3 then extn = extn3 end if
   if day == 23 then extn = extn3 end if
   print_string(serial_hw_data,extn)
   serial_hw_data = " "
end procedure

procedure display_month() is
   if month == 1 then print_string(serial_hw_data,month1) end if
   if month == 2 then print_string(serial_hw_data,month2) end if
   if month == 3 then print_string(serial_hw_data,month3) end if
   if month == 4 then print_string(serial_hw_data,month4) end if
   if month == 5 then print_string(serial_hw_data,month5) end if
   if month == 6 then print_string(serial_hw_data,month6) end if
   if month == 7 then print_string(serial_hw_data,month7) end if
   if month == 8 then print_string(serial_hw_data,month8) end if
   if month == 9 then print_string(serial_hw_data,month9) end if
   if month == 10 then print_string(serial_hw_data,month10) end if
   if month == 11 then print_string(serial_hw_data,month11) end if
   if month == 12 then print_string(serial_hw_data,month12) end if
   serial_hw_data = " "
end procedure

procedure set_date() is

   old_set = weekday
   display_weekday()
   while set loop
      if !up then weekday = weekday + 1 end if
      if !down then weekday = weekday - 1 end if
      delay_100ms(3)
      if weekday > 6 then weekday = 0 end if
      if weekday == 255 then weekday = 6 end if
      if weekday != old_set then
         old_set = weekday
         display_weekday()
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x06,weekday)
   delay_100ms(10)

   old_set = day
   display_day_of_month()
   while set loop
      if !up then day = day + 1 end if
      if !down then day = day - 1 end if
      delay_100ms(3)
      if day > 31 then day = 1 end if
      if day == 0 then day = 31 end if
      if day != old_set then
         old_set = day
         display_day_of_month()
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x05,day)
   delay_100ms(10)

   old_set = month
   display_month()
   while set loop
      if !up then month = month + 1 end if
      if !down then month = month - 1 end if
      delay_100ms(3)
      if month == 13 then month = 1 end if
      if month == 0 then month = 12 end if
      if month != old_set then
         old_set = month
         display_month()
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x07,month)
   delay_100ms(10)

   old_set = year
   print_byte_dec(serial_hw_data,years)
   print_byte_dec(serial_hw_data,year)
   serial_hw_data = " "
   while set loop
      if !up then year = year + 1 end if
      if !down then year = year - 1 end if
      delay_100ms(3)
      if year == 100 then year = 0 end if
      if year == 255 then year = 99 end if
      if year != old_set then
         old_set = year
         print_byte_dec(serial_hw_data,year)
         serial_hw_data = " "
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x08,year)
   print_byte_dec(serial_hw_data,years)
   print_byte_dec(serial_hw_data,year)
   serial_hw_data = " "

end procedure

procedure set_time() is

   old_set = hour
   print_byte_dec(serial_hw_data,hour)
   serial_hw_data = " "
   delay_100ms(10)
   while set loop
      if !up then hour = hour + 1 end if
      if !down then hour = hour - 1 end if
      delay_100ms(3)
      if hour == 24 then hour = 0 end if
      if hour == 255 then hour = 23 end if
      if hour != old_set then
         old_set = hour
         print_byte_dec(serial_hw_data,hour)
         serial_hw_data = " "
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x04,hour)
   delay_100ms(10)
   old_set = min
   print_byte_dec(serial_hw_data,min)
   serial_hw_data = " "
   while set loop
      if !up then min = min + 1 end if
      if !down then min = min - 1 end if
      delay_100ms(3)
      if min == 60 then min = 0 end if
      if min == 255 then min = 59 end if
      if min != old_set then
         old_set = min
         print_byte_dec(serial_hw_data,min)
         serial_hw_data = " "
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x03,min)
   delay_100ms(10)
   old_set = sec
   while set loop
      if !up | !down then sec = 00 end if
      delay_100ms(3)
      format_time_hms(serial_hw_data,hour,min,sec)
      serial_hw_data = " "
      if sec != old_set then
         old_set = sec
         pcf8563_register_write(pcf8563_address,0x02,00)
      end if
   end loop
end procedure

; read time and date registers

procedure menu() is

   print_string(serial_hw_data, time)
   serial_hw_data = " "
   while down loop
      delay_100ms(3)
      if !up then
         set_time()
         print_string(serial_hw_data, time)
         serial_hw_data = " "
      end if
   end loop
   delay_100ms(10)

   print_string(serial_hw_data, date)
   serial_hw_data = " "
   while down loop
      delay_100ms(3)
      if !up then
         set_date()
         print_string(serial_hw_data, date)
         serial_hw_data = " "
      end if
   end loop
   delay_100ms(10)

;   while down loop
;       delay_100ms(3)
;      if !up then set_shack()
;   end loop

end procedure

forever loop

   if !set then menu() end if
   read_pcf8563(pcf8563_address,fail,sec,min,hour,day,month,weekday,year)

   if != fail then
      print_string(serial_hw_data, str1)
      serial_hw_data = " "
   end if

   format_time_hms(serial_hw_data,hour,min,sec)
   serial_hw_data = " "

   display_weekday()
   display_day_of_month()
   display_month()

   print_byte_dec(serial_hw_data,years)
   print_byte_dec(serial_hw_data,year)
   serial_hw_data = " "

   print_crlf(serial_hw_data)
   led = on
   delay_100ms(9)
   led = off

end loop

Generated by JALlib CHM Help System | Source: rtc_pcf8563.jal


period_skip.jal - JALLIB Library Documentation

period_skip.jal JALLIB LIBRARY

Title

motor speed control by skipping periods of AC mains

Author

Eur van Andel, eur@fiwihex.nl (c) 2009

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

AC induction motors are low-priced, very reliable and widely available.
This library provides a way to control the speed of these motors, if they have reasonably
angular momentum.
--
Explanation: this is *NOT* phase control: http://en.wikipedia.org/wiki/Phase_control
Phase control makes a lot of noise, both audible and electrical.
--
This is deliberate skipping of half-waves. There are only 100 half-waves per second
@ 50 Hz and bit-fine control of motor speed would result in long duty cycles (2.55s)
with varying motor speeds and audible pitch change.
So we keep the period cycle at 32 half waves, with 8 duty cycles that only differ
one half-wave to minimise audible noise.
Electrical noise is minimized by zero-voltage switching.

Sources

Fairchild Application Note AN-3004, http://www.fairchildsemi.com/an/AN/AN-3004.pdf
http://www.sullivan-county.com/ele/triacs2.htm for schematics and examples how
to generate a zero-crossing signal.

speed duty cycle on duty cycle off
0 0 0 0 0 0 0 0 0 32 32 32 32 32 32 32 32
1 1 0 0 0 0 0 0 0 31 32 32 32 32 32 32 32
2 1 0 0 0 1 0 0 0 31 32 32 32 31 32 32 32
3 1 0 0 1 0 0 1 0 31 32 32 31 32 32 31 32
4 1 0 1 0 1 0 1 0 31 32 31 32 31 32 31 32
5 1 0 1 0 1 1 0 1 31 32 31 32 31 31 32 31
6 1 1 0 1 1 0 1 1 31 31 32 31 31 32 31 31
7 1 1 0 1 1 1 1 1 31 31 32 31 31 31 31 31
8 1 1 1 1 1 1 1 1 31 31 31 31 31 31 31 31
9 2 1 1 1 1 1 1 1 30 31 31 31 31 31 31 31

all the way to 255:

255 32 32 31 32 32 32 32 32 0 0 1 0 0 0 0 0

Since 256 would be full speed. At 255 the motor misses one half wave every 2.55 seconds,
which is 99.6% of full speed.

Requirements:

1) output pin labeled "triac", connected to a TRIAC, for instance via a MOC3042
zero-crossing opto-isolated triac driver, so that the TRIAC is on when the pin is high.

2) zero-crossing interrupt pin (B0), rising where mains voltage is zero, for instance
with an HPCL354 optocoupler and a 10k pullup resistor.

3) byte variable labeled "speed" with value ranging from 0...255

4) if speed changes, the procedure ps_adjust_period() should be called

5) ps_check_period() should be called at least every 320 ms, not once a month :-)
for 60 Hz mains frequency, call this procedure at least every 266 ms

var bit triac is pin_a0 -- pin connected to optotriac
pin_a0_direction = output
pin_b0_direction = input
var byte ps_speed = 0 -- 0..255 speed control, should be declared in main app

Constants and Variables

ps_on_period - var byte = 0

Routines

  • RTC - Procedure
  • ps_adjust_period - Procedure
  • ps_check_period - Procedure


philips_rc5_message_received - JALlib Procedures Help

philips_rc5_message_received JALLIB FUNCTION

Signature

function philips_rc5_message_received() return bit is

Description

Returns TRUE is a valid RC5 Remote Control message was received.

Include

To use this procedure, include the library:

include philips_rc_decoder

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f877a_philips_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title:Sample program for the Philips Remote Control Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows Philips Remote Control commands on an
--              serial interface using the external interrupt of the PIC.
--
-- Notes:       The 36 kHz Infra Red receiver (active low)  must be connected
--              to the external interrupt pin.
--

include 16f877a                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming, pull PGM pin LOW for normal operation

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Serial hardware pin aliases.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
serial_hw_init()
include print

-- Settings for the Philips Remote Control Decoder. Decoder times are based
-- on Timer 1 running at 1.0 MHz. Since 20 MHz will not give exactly
-- 1 MHz we do the following:
-- -) Use Fosc/4. This gives 5 MHz.
-- -) Use a prescaler of 1:4. This gives 1.25 MHz.
T1CON_TMR1CS = FALSE -- Clock source Fosc/4 gives 5 MHz
T1CON_T1CKPS = 0b10  -- Prescaler 1:4 gives 1.25 MHz
-- Since the clock runs 1.25 times faster than the default of 1 MHz
-- we need to scale the bit times accordingly (see library).
const dword PHILIPS_RC_SCALING = 125
-- Interrupt pin.
alias philips_rc_decoder_pin_direction is pin_b0_direction
-- Now we can include the library.
include philips_rc_decoder
philips_rc_decoder_init()

var word repeat_counter = 0
var byte last_address = 255
var byte last_command = 255
var bit  last_toggle = FALSE
var bit  rc5_received = FALSE
var bit  rc6_received = FALSE

-- ------- Procedures ------------------------

-- Print the received remote control data. When data is requested
-- the remote control message received flag is cleared.
procedure print_remote_control_data() is

   var byte command, address
   var bit toggle

   philips_rc_get_data(toggle, address, command)
   -- If new data is received, the repeat counter is reset.
   if (last_toggle != toggle) | (last_address != address) |
      (last_command != command) then
      repeat_counter = 0
      last_toggle = toggle
      last_address = address
      last_command = command
   else
      repeat_counter = repeat_counter + 1
   end if

   -- Print the contents of the RC5 or RC6 message.
   if toggle then
      print_string(serial, "Toggle bit: 1, ")
   else
      print_string(serial, "Toggle bit: 0, ")
   end if

   print_string(serial, "Address: ")
   print_byte_dec(serial, address)

   print_string(serial, ", Command: ")
   print_byte_dec(serial, command)

   print_string(serial, ", Repeat: ")
   print_word_dec(serial, repeat_counter)
   print_crlf(serial)

end procedure

-- -------- Main program starts here -------------

print_crlf(serial)
print_string(serial,"PHILIPS RC5/RC6 MODE 0 REMOTE CONTROL DECODER.\r\n")

forever  loop

   if philips_rc5_message_received()then
      print_string(serial, "Message: RC5, ")
      rc5_received = TRUE
      if rc6_received then
         rc6_received = FALSE
         repeat_counter = 0
      end if
      -- Print the data. This will also clear the message received.
      print_remote_control_data()
   elsif philips_rc6_message_received then
      print_string(serial, "Message: RC6, ")
      rc6_received = TRUE
      if rc5_received then
         rc5_received = FALSE
         repeat_counter = 0
      end if
      -- Print the data. This will also clear the message received.
      print_remote_control_data()
   end if

end loop

Generated by JALlib CHM Help System | Source: philips_rc_decoder.jal


philips_rc_decoder.jal - JALLIB Library Documentation

philips_rc_decoder.jal JALLIB LIBRARY

Title

Philips Infra Red Remote Control Decoder Library.

Author

Rob Jansen, Copyright (c) 2023..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for decoding Philps RC5 (extended) and RC6 mode 0
Remote Control messages.
The library can be configured to use either the external interrupt
(0) or an IOC interrupt to decode the Remote Control Messages.
The default is using an external interupt (0). In order to switch
to using an IOC interrupt the user must initialize the IOC
to be active on both the rising and falling edge and must
define the following alias (example for IOC on pin A2):
alias philips_rc_decoder_ioc_flag is IOCAF_IOCAF2
The library uses Timer 1 to measure the the bit times
The user must initialize Timer 1. Bit times are based on 1 us.
If Timer 1 does not run at 1 MHz then the user has to define
the dword constant PHILIPS_RC_SCALING, where a value of 100 equals
Timer 1 running at 1 MHz. When Timer 1 runs at 1.25 MHz the
dword constant PHILIPS_RC_SCALING must equal 125. Same when
Timer 1 runs at 0.75 MHz PHILIPS_RC_SCALING must equal 75.

Notes

The 36 kHz Infra Red receiver (active low) must be connected
to the external interrupt pin or the used IOC pin.

Sources

Documentation on RC5 and RC6 mode 0 protocol.
https://en.wikipedia.org/wiki/RC-5

----------------------------------------------------------------------------
-------------------------- Public API --------------------------------------
----------------------------------------------------------------------------

----------------------------------------------------------------------------
Initialize the Philps RC5/RC6 Remote Control Decoder. This will enable the
interrupts used by this library.
----------------------------------------------------------------------------

Constants and Variables

PHILIPS_RC_SCALING - const dword = 100
PHILIPS_RC5_BITS - const byte = 13 -- Number of bits in RC5 message
Number of bits in RC5 message
PHILIPS_RC6_BITS - const byte = 21 -- Number of bits in RC6 message
Number of bits in RC6 message

Routines

  • _philips_rc_get_timer1_value - Function returns word
  • _philips_rc_handle_interrupt_flag - Function returns bit
  • _philips_rc_interrupt - Procedure
  • _philips_rc_reset_decoder - Procedure
  • _philips_rc_timer1_interrupt - Procedure
  • _philips_rc_timer1_preset - Procedure
  • philips_rc5_message_received - Function returns bit
  • philips_rc6_message_received - Function returns bit
  • philips_rc_decoder_init - Procedure
  • philips_rc_get_data - Procedure


philips_rc_decoder_init - JALlib Procedures Help

philips_rc_decoder_init JALLIB PROCEDURE

Signature

procedure philips_rc_decoder_init() is

Description

Initialize the Philps RC5/RC6 Remote Control Decoder. This will initialize
the required interrupts.

Include

To use this procedure, include the library:

include philips_rc_decoder

Parameters

None

Return Value

None

Example

From sample file: 16f877a_philips_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title:Sample program for the Philips Remote Control Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows Philips Remote Control commands on an
--              serial interface using the external interrupt of the PIC.
--
-- Notes:       The 36 kHz Infra Red receiver (active low)  must be connected
--              to the external interrupt pin.
--

include 16f877a                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming, pull PGM pin LOW for normal operation

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Serial hardware pin aliases.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
serial_hw_init()
include print

-- Settings for the Philips Remote Control Decoder. Decoder times are based
-- on Timer 1 running at 1.0 MHz. Since 20 MHz will not give exactly
-- 1 MHz we do the following:
-- -) Use Fosc/4. This gives 5 MHz.
-- -) Use a prescaler of 1:4. This gives 1.25 MHz.
T1CON_TMR1CS = FALSE -- Clock source Fosc/4 gives 5 MHz
T1CON_T1CKPS = 0b10  -- Prescaler 1:4 gives 1.25 MHz
-- Since the clock runs 1.25 times faster than the default of 1 MHz
-- we need to scale the bit times accordingly (see library).
const dword PHILIPS_RC_SCALING = 125
-- Interrupt pin.
alias philips_rc_decoder_pin_direction is pin_b0_direction
-- Now we can include the library.
include philips_rc_decoder
philips_rc_decoder_init()

var word repeat_counter = 0
var byte last_address = 255
var byte last_command = 255
var bit  last_toggle = FALSE
var bit  rc5_received = FALSE
var bit  rc6_received = FALSE

-- ------- Procedures ------------------------

-- Print the received remote control data. When data is requested
-- the remote control message received flag is cleared.
procedure print_remote_control_data() is

   var byte command, address
   var bit toggle

   philips_rc_get_data(toggle, address, command)
   -- If new data is received, the repeat counter is reset.
   if (last_toggle != toggle) | (last_address != address) |
      (last_command != command) then
      repeat_counter = 0
      last_toggle = toggle
      last_address = address
      last_command = command
   else
      repeat_counter = repeat_counter + 1
   end if

   -- Print the contents of the RC5 or RC6 message.
   if toggle then
      print_string(serial, "Toggle bit: 1, ")
   else
      print_string(serial, "Toggle bit: 0, ")
   end if

   print_string(serial, "Address: ")
   print_byte_dec(serial, address)

   print_string(serial, ", Command: ")
   print_byte_dec(serial, command)

   print_string(serial, ", Repeat: ")
   print_word_dec(serial, repeat_counter)
   print_crlf(serial)

end procedure

-- -------- Main program starts here -------------

print_crlf(serial)
print_string(serial,"PHILIPS RC5/RC6 MODE 0 REMOTE CONTROL DECODER.\r\n")

forever  loop

   if philips_rc5_message_received()then
      print_string(serial, "Message: RC5, ")
      rc5_received = TRUE
      if rc6_received then
         rc6_received = FALSE
         repeat_counter = 0
      end if
      -- Print the data. This will also clear the message received.
      print_remote_control_data()
   elsif philips_rc6_message_received then
      print_string(serial, "Message: RC6, ")
      rc6_received = TRUE
      if rc5_received then
         rc5_received = FALSE
         repeat_counter = 0
      end if
      -- Print the data. This will also clear the message received.
      print_remote_control_data()
   end if

end loop

Generated by JALlib CHM Help System | Source: philips_rc_decoder.jal


philips_rc_get_data - JALlib Procedures Help

philips_rc_get_data JALLIB PROCEDURE

Signature

procedure philips_rc_get_data(bit out toggle, byte out address, byte out command) is

Description

Return the last received RC5 or RC6 data. After called, the message received
flags are cleared.

Include

To use this procedure, include the library:

include philips_rc_decoder

Parameters

  • toggle - bit out
  • address - byte out
  • command - byte out

Return Value

None

Example

From sample file: 16f877a_philips_rc_decoder_serial.jal

-- -----------------------------------------------------------------------------
-- Title:Sample program for the Philips Remote Control Decoder
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program that shows Philips Remote Control commands on an
--              serial interface using the external interrupt of the PIC.
--
-- Notes:       The 36 kHz Infra Red receiver (active low)  must be connected
--              to the external interrupt pin.
--

include 16f877a                     -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target LVP      ENABLED      -- low voltage programming, pull PGM pin LOW for normal operation

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(250_000)

-- Serial hardware pin aliases.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
serial_hw_init()
include print

-- Settings for the Philips Remote Control Decoder. Decoder times are based
-- on Timer 1 running at 1.0 MHz. Since 20 MHz will not give exactly
-- 1 MHz we do the following:
-- -) Use Fosc/4. This gives 5 MHz.
-- -) Use a prescaler of 1:4. This gives 1.25 MHz.
T1CON_TMR1CS = FALSE -- Clock source Fosc/4 gives 5 MHz
T1CON_T1CKPS = 0b10  -- Prescaler 1:4 gives 1.25 MHz
-- Since the clock runs 1.25 times faster than the default of 1 MHz
-- we need to scale the bit times accordingly (see library).
const dword PHILIPS_RC_SCALING = 125
-- Interrupt pin.
alias philips_rc_decoder_pin_direction is pin_b0_direction
-- Now we can include the library.
include philips_rc_decoder
philips_rc_decoder_init()

var word repeat_counter = 0
var byte last_address = 255
var byte last_command = 255
var bit  last_toggle = FALSE
var bit  rc5_received = FALSE
var bit  rc6_received = FALSE

-- ------- Procedures ------------------------

-- Print the received remote control data. When data is requested
-- the remote control message received flag is cleared.
procedure print_remote_control_data() is

   var byte command, address
   var bit toggle

   philips_rc_get_data(toggle, address, command)
   -- If new data is received, the repeat counter is reset.
   if (last_toggle != toggle) | (last_address != address) |
      (last_command != command) then
      repeat_counter = 0
      last_toggle = toggle
      last_address = address
      last_command = command
   else
      repeat_counter = repeat_counter + 1
   end if

   -- Print the contents of the RC5 or RC6 message.
   if toggle then
      print_string(serial, "Toggle bit: 1, ")
   else
      print_string(serial, "Toggle bit: 0, ")
   end if

   print_string(serial, "Address: ")
   print_byte_dec(serial, address)

   print_string(serial, ", Command: ")
   print_byte_dec(serial, command)

   print_string(serial, ", Repeat: ")
   print_word_dec(serial, repeat_counter)
   print_crlf(serial)

end procedure

-- -------- Main program starts here -------------

print_crlf(serial)
print_string(serial,"PHILIPS RC5/RC6 MODE 0 REMOTE CONTROL DECODER.\r\n")

forever  loop

   if philips_rc5_message_received()then
      print_string(serial, "Message: RC5, ")
      rc5_received = TRUE
      if rc6_received then
         rc6_received = FALSE
         repeat_counter = 0
      end if
      -- Print the data. This will also clear the message received.
      print_remote_control_data()
   elsif philips_rc6_message_received then
      print_string(serial, "Message: RC6, ")
      rc6_received = TRUE
      if rc5_received then
         rc5_received = FALSE
         repeat_counter = 0
      end if
      -- Print the data. This will also clear the message received.
      print_remote_control_data()
   end if

end loop

Generated by JALlib CHM Help System | Source: philips_rc_decoder.jal


pic_data_eeprom.jal - JALLIB Library Documentation

pic_data_eeprom.jal JALLIB LIBRARY

Title

reading/writing of PIC's data EEPROM

Author

Stef Mientki, Copyright (c) 2002..2022, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Joep Suijs (on behalf of Tijs van Roon),

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Read from or write to EEPROM/data a byte, word or double word.
Available procedures:
* data_eeprom_read(<offset>,<byte>)
* data_eeprom_write(<offset>,<byte>)
* data_eeprom_read_word(<offset>,<word>)
* data_eeprom_write_word(<ofset>,<word>)
* data_eeprom_read_dword(<offset>,<dword>)
* data_eeprom_write_dword(<offset>,<dword>)
Available functions:
* <byte> = data_eeprom(<offset>)
* <word> = data_eeprom_word(<offset>)
* <dword> = data_eeprom_dword(<offset>)
In all cases <offset> is a word containing the position relative to
the beginning of EEPROM/data memory.
Examples of use:
* Read a byte of EEPROM at offset 7 into x:
var byte x
data_eeprom_read(7, x)
* Read a word from EEPROM at offset 4 into y:
var word y
y = data_eeprom_word(4)
* Write a byte to EEPROM at offset 18:
data_eeprom_write(18, 0b1111_0000)

Notes

* Write-protect bits in configuration memory may prohibit writing.
* Writing to locations outside the available memory range may have
unexpected effects!
* For most PICs the first EEPROM address starts at 0. For some PICs,
this is not the case and and an offset must be added to the EEPROM address
If an offset is needed the main program can define a constant called
EEPROM_ADDRESS_OFFSET with the correct value so that the first
address of the EEPROM remains 0 for the user. Some examples:
For PIC16F18346: const word EEPROM_ADDRESS_OFFSET = 0x7000
For PIC18F46Q10: const dword EEPROM_ADDRESS_OFFSET = 0x31_0000
See the datasheet of the PICs for more information.

Alias to support differences in PICs. Read bit.

Routines

  • _prepare_eeprom_access - Procedure
  • data_eeprom - Function returns byte
  • data_eeprom_dword - Function returns dword
  • data_eeprom_read - Procedure
  • data_eeprom_read_dword - Procedure
  • data_eeprom_read_word - Procedure
  • data_eeprom_word - Function returns word
  • data_eeprom_write - Procedure
  • data_eeprom_write_dword - Procedure
  • data_eeprom_write_word - Procedure


pic_data_hef.jal - JALLIB Library Documentation

pic_data_hef.jal JALLIB LIBRARY

Title

Read byte from data HEF at given offset

Author

Rob Jansen, Copyright (c) 2020..2020, all rights reserved., Adapted-by:

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Read from or write to HEF/data a byte, word or double word.
Available procedures:
* data_hef_read(<offset>,<byte>)
* data_hef_write(<offset>,<byte>)
* data_hef_read_word(<offset>,<word>)
* data_hef_write_word(<offset>,<word>)
* data_hef_read_dword(<offset>,<dword>)
* data_hef_write_dword(<offset>,<dword>)
Available functions:
* <byte> = data_hef(<offset>)
* <word> = data_hef_word(<offset>)
* <dword> = data_hef_dword(<offset>)
In all cases <offset> must be in the range of the High Endurance Flash
Examples of use:
* Read a byte of HEF at offset 7 into x:
var byte x
data_hef_read(7, x)
* Read a word from HEF at offset 4 into y:
var word y
y = data_hef_word(4)
* Write a byte to HEF at offset 18:
data_hef_write(18, 0b1111_0000)

Notes

* You must always define the HEF offset address (start address of the HEF)
by definining a connstant called HEF_ADDRESS_OFFSET with the correct value.
See the datasheet of the PICs for more information.
* Write-protect bits in configuration memory may prohibit writing.
* Writing to locations outside the available memory range may have
unexpected effects!

-----------------------------------------------------------------------------
-------------------------- Public API ---------------------------------------
-----------------------------------------------------------------------------

------------------------------------------------------------------------

Sources

AN1673. Using the PIC16F1XXX High-Endurance Flash (HEF) Block.

Routines

  • _hef_erase - Procedure
  • _hef_read_byte - Function returns byte
  • _hef_unlock - Procedure
  • _hef_write_byte - Procedure
  • _hef_write_flash - Procedure
  • data_hef - Function returns byte
  • data_hef_dword - Function returns dword
  • data_hef_read - Procedure
  • data_hef_read_dword - Procedure
  • data_hef_read_word - Procedure
  • data_hef_word - Function returns word
  • data_hef_write - Procedure
  • data_hef_write_dword - Procedure
  • data_hef_write_word - Procedure


pintools.jal - JALLIB Library Documentation

pintools.jal JALLIB LIBRARY

Title

Set pin level

Author

Sebastien Lelong, Copyright (C) 2009, all rights reserved., Adapted-by: Rob Hamerling

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides a set of functions and procedures
to help users manipulating pins. For instance, you can dynamically access pins
using a specific mapping (RA0 is #0, RB1 is #2, etc...) and act on levels and
directions.
.
Using this library requires that an array "pintools_map" is defined before
including the library. This byte array is populated by pairs of elements:
* the first element of a pair corresponds to the port letter ("A", "B", ...)
* the second element of a pair is the pin number in this port (0, 1, 2, ...)
Pins can then be accessed with their index in this array.
Example: const byte pintools_map[] = { "A",1, "B",1, "D",3 }
This 6 elements array (of 3 pairs) specifies that:
* pin #0 refers to pin_A1
* pin #1 refers to pin_B1
* pin #2 refers to pin_D3
Example of use:
* To obtain the current level of pin_B1:
pin_level = pintools_level[1]
* To set the direction of pin_D3 to output:
pintools_direction[2] = OUTPUT

Notes

------------------------------------------------------------------------------

Routines

  • pintools_direction'get - Function returns bit
  • pintools_direction'put - Procedure
  • pintools_level'get - Function returns bit
  • pintools_level'put - Procedure


pll_mc145156.jal - JALLIB Library Documentation

pll_mc145156.jal JALLIB LIBRARY

Title

Library to manage the pll chip MC145156 from Motorola

Author

Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved.

Compiler

>=2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library files implement the procedures to manage a PLL system using the
Motorola MC145156[-1|-2] chips
--
A PLL is a Phase Locked Loop, a kind of Controlled oscillator used in base/mobile/handheld
radios before the invention of the DDS chips.
--
A PLL is no more than a Voltage Controled Oscillator (VCO) that is controled by the phase
difference of it's output compared against a reference, usualy the comparison is made
after a programable division of the output of the VCO. In this case with a dual modulus prescaler
--
I assume that you know how all this work, if not please ask to google...
--
All you need is the reference frequency, by the datasheet this is calculated by the Xtal
the division ratio configured in the pins RA0..RA2, see datasheet page 14 (look for a table)
this will be called "PLL_R" and expressed in Khz
--
Then you need to know the simple division ratio of your prescaler, mine is 64 (64/65), this is
called "PLL_P"
--
From the math from the datasheet you need to calculate the register N and A, I solved that for you
--
Nt = (Desired_freq/Reference_freq); but also Nt = (N*P)+A
--
So, to calculate N and A registers (pll_N and pll_A in this lib) you need to know the desired freq
for example 145000Khz
--
Nt = 145000/5 = 29000; N = Nt/P
A = Nt - (N*P)
--
Next step is to send the info via SPI to the chip. For that you need three pins
in this case we use pll_clk, pll_dat and pll_ena aliases, and if your circuit need to send sw1 & sw2
you must define its value at load time in normal condition and then you can vary it

Notes

* Release date: 11 Nov 2014

sanity checks

vars used internally on the lib

Sources

Motorola Datasheet

Routines

  • _calc - Procedure
  • _pll_rset - Procedure
  • _sendbit - Procedure
  • pll_set - Procedure


pll_set - JALlib Procedures Help

pll_set JALLIB PROCEDURE

Signature

procedure pll_set(dword in freq) is

Description

No description available.

Include

To use this procedure, include the library:

include pll_mc145156

Parameters

  • freq - dword in

Return Value

None

Example

From sample file: 18f14k50_pll.jal

-- --------------------------------------------------------------------------------------------
-- Title: Example of the Motorola MC145156 PLL IC Lib using a PIC18F14K50
-- Author: Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved.
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Example of use of the PLL lib for the MC145156 IC. This example is for demostrating the
-- capabilities of jallib to manage the IC to revive an ancient VHF tranceiver from the
-- Yaesu house: an FT-23R
-- --
-- This tranceiver has afully functional system with the MC145156-2, the only thing you need to
-- know is how to wire the data, clock and enable wires
-- --
-- Other technical details: the IC has a 10.240 Mhz XTAL as the reference and is configured
-- to divide by 2048, that gives you a 5Khz reference clock and minimum step; the prescaler is a
-- common dual modulus 64/65 one.
--
-- Sources:
-- Thechnical Suplement for the Yaesy FT-23R in the internet, the datasheet of the MC145156-2,
-- datasheet of the prescaller and a old FT-23R
--
-- Notes:
-- * This file is maintained by hand!!!
-- * The goal of the lib is to make a simple VHF signal (RF) generator for VHF testing/repairing
--   this is only a demo of the capabilities.
-- * With my stock hardware the generator can cover ~116 to ~150 Mhz, with modifications & tweaking
--  (VCC increased from 5V to 8V and some adjustments) it can cover now from ~100 to 190 Mhz
--

-- device map
--             +VCC [1     20] GND
--               A5 [2     19] PGD
--               A4 [3     18] PGC
--        MCLR > A3 [4     17] +VUSB
--         DAT < C5 [5     16] C0 > d7  |
--         CLK < C4 [6     15] C1 > d6  | LCD 4 bits
--         ENB < C3 [7     14] C2 > d5  |
--               C6 [8     13] B4 > d4  |
--       abajo > C7 [9     12] B5 > RS  |
--      arriba > B7 [10    11] B6 > EN  |

-- include the device
include	18F14K50	-- target PICmicro
pragma target clock       16_000_000

-- fuses
WDTCON_SWDTEN               = OFF           -- WDT off
OSCCON_SCS                  = 0b10          -- Clock Source is internal
OSCCON_IRCF                 = 0b111         -- The internal Clock sources is set to 16 Mhz
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           INTOSC_NOCLKOUT
pragma target PLLEN         DISABLED
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          INTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

-- All digital
enable_digital_io()

-- ### LCD @ 4 bits (1x16)
const		byte		LCD_ROWS		= 1
const		byte		LCD_CHARS		= 16
alias		lcd_d4		is pin_B4
alias		lcd_d5		is pin_C2
alias		lcd_d6		is pin_C1
alias		lcd_d7		is pin_C0
alias		lcd_rs		is pin_B5
alias		lcd_en		is pin_B6
-- all lcd pins to output
pin_B4_direction		= output
pin_B5_direction		= output
pin_B6_direction		= output
pin_C0_direction		= output
pin_C1_direction		= output
pin_C2_direction		= output
-- loading and init...
include lcd_hd44780_4
lcd_init()

-- include delay lib
include delay

-- setup the format lib to show data to the lcd
include format
include print

-- pins for up/down with external pull-ups of 10k
-- alias
alias UP is pin_B7
alias DOWN is pin_C7
-- dir
pin_B7_direction	= input
pin_C7_direction	= input

-- pins for PLL, alias
alias pll_dat is pin_C5
alias pll_clk is pin_C4
alias pll_en is pin_C3
-- dirs
pin_C5_direction	= output
pin_C4_direction	= output
pin_C3_direction	= output

-- debounce
include debounce

-- variables
var dword freq = 145_000	-- the initial freq in Khzm this is a common Ham radio freq
-- debounce ones
var word updb = debounce_init(255)
var word dwdb = debounce_init(255)
-- temp
var word tword

-- setup of the PLL lib
const byte PLL_R = 5		-- 5 Khz of minimun step
const byte PLL_P = 64		-- prescaler simple value, in my case 64/65
include pll_mc145156
pll_init(freq)			-- set the initial freq to 145.000 Mhz as predefined before

procedure showit() is
   -- update the LCD
   lcd_cursor_position(0,0)
   print_string(lcd,"Freq ")
   format_dword_dec(lcd,freq,6,3)
   print_string(lcd," Mhz")
end procedure

-- WELCOME of the LCD
lcd_cursor_position(0,0)
--                0123456789abcdef
print_string(lcd,"PLL test FT-23R ")
-- delay
delay_1s(5)
--
lcd_cursor_position(0,0)
--                0123456789abcdef
print_string(lcd,"As RF Generator ")
-- delay
delay_1s(5)

var bit show = on

-- forever loop, fun is down here
forever loop
   -- I need to update the LCD & PLL?
   if (show == on) then
      -- Set the PLL to the new freq
      pll_set(freq)
      -- Show it on the LCD
      showit()
      -- flag down
      show = off
   end if
   --
   -- check for inputs
   -- UP first...
   tword = debounce(UP, updb)
   if (tword == 2) then
      -- +1 and update
      freq = freq + PLL_R
      show = on
   end if
   --
   -- DOWN ...
   tword = debounce(DOWN, dwdb)
   if (tword == 2) then
      -- -1 and update
      freq = freq - PLL_R
      show = on
   end if
end loop

Generated by JALlib CHM Help System | Source: pll_mc145156.jal


polar_to_cartesian - JALlib Procedures Help

polar_to_cartesian JALLIB PROCEDURE

Signature

procedure polar_to_cartesian(sword in radius, sword in angle, sword out xpos, sword out ypos) is

Description

Title: Convert polar to cartesian coo-ordinates
Arguments: - radius (signed word)
- angle in degrees (signed word)
Returns: - X-co-ordinate (signed word)
- Y-co-ordinate (signed word)
Original: Michael Watterson
Notes: Use to rotate angle of a line by calculating endpoints.
Use to generate quadrature waves by changing angle at a fixed speed.
If using all 360 degrees in one degree steps, then frequency is step rate / 360

Include

To use this procedure, include the library:

include math

Parameters

  • radius - sword in
  • angle - sword in
  • xpos - sword out
  • ypos - sword out

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: math.jal


pps.jal - JALLIB Library Documentation

pps.jal JALLIB LIBRARY

Title

Peripheral Pin Select (PPS) library

Author

Sebastion Lelong, Copyright (c) 2011..2021, All rights reserved., Adapted-by: Rob Hamerling, Rob Jansen, Oliver "Kiste" Seitz

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library supports Peripheral Pin Select of 3 major groups
of PICs, with significant differences in the PPS implementation:
- 18F PICs with PPS (18FXXJ11, 18FXXJ13, 18FXXJ50, 18FXXJ53)
- 18F PICs with PPS-light (high end PICs 18fxxj94/99)
- Enhanced Midrange (16f15xx, 16f16xx, 16f17xx, 16f18xxx and lf variants).
Within these groups there are minor differences, such that we distinguish
5 PPS_GROUPS: PPS_1 for 18FxxJ11, 18FxxJ50
PPS_2 for 18FxxJ13, 18FxxJ53
PPS_3 for 18FxxJ94, 18FxxJ99
PPS_4 for 16F16xx, 16f17xx (without PMD0 register)
PPS_5 for 16F15xxx, 16f18xxx, 18FxxK40 (with PMD0 register)
The actual PPS-group is specified in the device file of each PIC
(PPS_0 when the PIC has no PPS).
For all groups the basic rules with PPS are:
* With OUTPUT a pin is assigned to a peripheral function
* with INPUT the peripheral function is assigned to a pin.
.
Using PPS to (re-)configure a PIC involves 3 stages:
1. The PPS module must be unlocked with:
pps_control_lock(FALSE)
2. Assign peripheral functions to specific pins.
This stage is somewhat different for each of the major groups.
PPS_1 and PPS_2:
Example to (re)map pins TX2 and RX2 of the USART2 of a 18f27j53:
To assign physical pin_B6 (alias pin_RP9) to the OUTPUT
of the USART2 (TX2) specify:
PPS_MAP_RP9 = PPS_TX2
To assign INPUT of the USART2 (RX2) to physical pin_B7
(alias RP10) specify:
PPS_MAP_RX2 = RP10
PPS_3:
Not supported yet.
PPS_4 and PPS_5:
Example to (re)map pins TX and RX of the USART of a 16f1708:
To assign physical pin_B7 to the OUTPUT of the USART (TX) specify:
RC7PPS = PPS_TX
To assign INPUT of the USART (RX) to physical pin_B6 specify:
RXPPS = PPS_RB6
For all PPS groups holds:
- Multiple peripheral functions can be mapped while the
PPS module is unlocked.
- For bi-directional peripherals INPUT and OUTPUT must be
mapped to the same physical pin.
3. Finally the PPS module must be locked with:
pps_control_lock(TRUE).
.
When 1-way locking is used with:
- for groups PPS_1, 2 and 3: pragma fuse_def IOL1WAY ENABLED
- for groups 4 and 5: pragma fuse_def PPS1WAY ENABLED
peripheral pins can be assigned only once. When the PPS module is locked
again further changes are ignored (until reset or power-off).
This is the default behaviour of the PIC!
When more than one unlock/remap/lock sequence is required specify:
for groups PPS_1, 2 and 3: pragma fuse_def IOL1WAY DISABLED
for groups PPS_4 and 5: pragma fuse_def PPS1WAY DISABLED

Notes

- This library is the original PPS library by Sebastien Lelong for
the 18Fs, extended by Rob Hamerling for the Enhanced Midrange.

Some newer PICs have INTCON registers named differently.

Sources

Microchip TB3130 - Peripheral Pin Select in 8-Bit Microcontrollers Technical Brief
TB3098 - PIC16F170X Peripheral Pin Select (PPS) Technical Brief
Datasheets of the applicable PICs

Constants and Variables

pps_gie_state - var bit = 0 -- interrupt state at unlock
interrupt state at unlock
PPS_NULL - const byte = 0 -- Disable RPn output function
Disable RPn output function
PPS_C1OUT - const byte = 1 -- Comparator 1 Output
Comparator 1 Output
PPS_C2OUT - const byte = 2 -- Comparator 2 Output
Comparator 2 Output
PPS_TX2CK2 - const byte = 5 -- EUSART2 Asynchronous Transmit/Synchronous clock
EUSART2 Asynchronous Transmit/Synchronous clock
PPS_TX2 - const byte = 5 -- EUSART2 Asynchronous Transmit
EUSART2 Asynchronous Transmit
PPS_CK2 - const byte = 5 -- EUSART2 Synchronous Clock Output
EUSART2 Synchronous Clock Output
PPS_DT2 - const byte = 6 -- EUSART2 Synchronous Transmit
EUSART2 Synchronous Transmit
PPS_SDO2 - const byte = 9 -- SPI2 Data Output
SPI2 Data Output
PPS_SCK2 - const byte = 10 -- SPI2 Clock Output
SPI2 Clock Output
PPS_SSDMA - const byte = 12 -- SPI DMA Slave Select
SPI DMA Slave Select
PPS_ULPOUT - const byte = 13 -- Ultra Low-Power Wake-Up Event
Ultra Low-Power Wake-Up Event
PPS_CCP1 - const byte = 14 -- ECCP1 Compare
ECCP1 Compare
PPS_P1A - const byte = 14 -- ECCP1 PWM Output Channel A
ECCP1 PWM Output Channel A
PPS_P1B - const byte = 15 -- ECCP1 PWM Output Channel B
ECCP1 PWM Output Channel B
PPS_P1C - const byte = 16 -- ECCP2 PWM Output Channel C
ECCP2 PWM Output Channel C
PPS_P1D - const byte = 17 -- ECCP1 PWM Output Channel D
ECCP1 PWM Output Channel D
PPS_CCP2 - const byte = 18 -- ECCP2 Compare
ECCP2 Compare
PPS_P2A - const byte = 18 -- ECCP2 PWM Output Channel A
ECCP2 PWM Output Channel A
PPS_P2B - const byte = 19 -- ECCP2 PWM Output Channel B
ECCP2 PWM Output Channel B
PPS_P2C - const byte = 20 -- ECCP2 PWM Output Channel C
ECCP2 PWM Output Channel C
PPS_P2D - const byte = 21 -- ECCP2 PWM Output Channel D
ECCP2 PWM Output Channel D
PPS_NULL - const byte = 0 -- Disable RPn output function
Disable RPn output function
PPS_C1OUT - const byte = 1 -- Comparator 1 Output
Comparator 1 Output
PPS_C2OUT - const byte = 2 -- Comparator 2 Output
Comparator 2 Output
PPS_C3OUT - const byte = 3 -- Comparator 3 Output
Comparator 3 Output
PPS_TX2CK2 - const byte = 6 -- EUSART2 Asynchronous Transmit/Synchronous clock
EUSART2 Asynchronous Transmit/Synchronous clock
PPS_TX2 - const byte = 6 -- EUSART2 Asynchronous Transmit
EUSART2 Asynchronous Transmit
PPS_CK2 - const byte = 6 -- EUSART2 Synchronous Clock Output
EUSART2 Synchronous Clock Output
PPS_DT2 - const byte = 7 -- EUSART2 Synchronous Transmit
EUSART2 Synchronous Transmit
PPS_SDO2 - const byte = 10 -- SPI2 Data Output
SPI2 Data Output
PPS_SCK2 - const byte = 11 -- SPI2 Clock Output
SPI2 Clock Output
PPS_SSDMA - const byte = 12 -- SPI DMA Slave Select
SPI DMA Slave Select
PPS_ULPOUT - const byte = 13 -- Ultra Low-Power Wake-Up Event
Ultra Low-Power Wake-Up Event
PPS_CCP1 - const byte = 14 -- ECCP1 Compare
ECCP1 Compare
PPS_P1A - const byte = 14 -- ECCP1 PWM Output Channel A
ECCP1 PWM Output Channel A
PPS_P1B - const byte = 15 -- ECCP1 PWM Output Channel B
ECCP1 PWM Output Channel B
PPS_P1C - const byte = 16 -- ECCP1 PWM Output Channel C
ECCP1 PWM Output Channel C
PPS_P1D - const byte = 17 -- ECCP1 PWM Output Channel D
ECCP1 PWM Output Channel D
PPS_CCP2 - const byte = 18 -- ECCP2 Compare
ECCP2 Compare
PPS_P2A - const byte = 18 -- ECCP2 PWM Output Channel A
ECCP2 PWM Output Channel A
PPS_P2B - const byte = 19 -- ECCP2 PWM Output Channel B
ECCP2 PWM Output Channel B
PPS_P2C - const byte = 20 -- ECCP2 PWM Output Channel C
ECCP2 PWM Output Channel C
PPS_P2D - const byte = 21 -- ECCP2 PWM Output Channel D
ECCP2 PWM Output Channel D
PPS_CCP3 - const byte = 22 -- ECCP3 Compare
ECCP3 Compare
PPS_P3A - const byte = 22 -- ECCP3 PWM Output Channel A
ECCP3 PWM Output Channel A
PPS_P3B - const byte = 23 -- ECCP3 PWM Output Channel B
ECCP3 PWM Output Channel B
PPS_P3C - const byte = 24 -- ECCP3 PWM Output Channel C
ECCP3 PWM Output Channel C
PPS_P3D - const byte = 25 -- ECCP3 PWM Output Channel D
ECCP3 PWM Output Channel D
RP0 - const byte = 0
RP1 - const byte = 1
RP2 - const byte = 2
RP3 - const byte = 3
RP4 - const byte = 4
RP5 - const byte = 5
RP6 - const byte = 6
RP7 - const byte = 7
RP8 - const byte = 8
RP9 - const byte = 9
RP10 - const byte = 10
RP11 - const byte = 11
RP12 - const byte = 12
RP13 - const byte = 13
RP14 - const byte = 14
RP15 - const byte = 15
RP16 - const byte = 16
RP17 - const byte = 17
RP18 - const byte = 18
RP19 - const byte = 19
RP20 - const byte = 20
RP21 - const byte = 21
RP22 - const byte = 22
RP23 - const byte = 23
RP24 - const byte = 24
PPS_RA0 - const byte = 0b00000_000
PPS_RA1 - const byte = 0b00000_001
PPS_RA2 - const byte = 0b00000_010
PPS_RA3 - const byte = 0b00000_011
PPS_RA4 - const byte = 0b00000_100
PPS_RA5 - const byte = 0b00000_101
PPS_RA6 - const byte = 0b00000_110
PPS_RA7 - const byte = 0b00000_111
PPS_RB0 - const byte = 0b00001_000
PPS_RB1 - const byte = 0b00001_001
PPS_RB2 - const byte = 0b00001_010
PPS_RB3 - const byte = 0b00001_011
PPS_RB4 - const byte = 0b00001_100
PPS_RB5 - const byte = 0b00001_101
PPS_RB6 - const byte = 0b00001_110
PPS_RB7 - const byte = 0b00001_111
PPS_RC0 - const byte = 0b00010_000
PPS_RC1 - const byte = 0b00010_001
PPS_RC2 - const byte = 0b00010_010
PPS_RC3 - const byte = 0b00010_011
PPS_RC4 - const byte = 0b00010_100
PPS_RC5 - const byte = 0b00010_101
PPS_RC6 - const byte = 0b00010_110
PPS_RC7 - const byte = 0b00010_111
PPS_RD0 - const byte = 0b00011_000
PPS_RD1 - const byte = 0b00011_001
PPS_RD2 - const byte = 0b00011_010
PPS_RD3 - const byte = 0b00011_011
PPS_RD4 - const byte = 0b00011_100
PPS_RD5 - const byte = 0b00011_101
PPS_RD6 - const byte = 0b00011_110
PPS_RD7 - const byte = 0b00011_111
PPS_RE0 - const byte = 0b00100_000
PPS_RE1 - const byte = 0b00100_001
PPS_RE2 - const byte = 0b00100_010
PPS_RE3 - const byte = 0b00100_011
PPS_RE4 - const byte = 0b00100_100
PPS_RE5 - const byte = 0b00100_101
PPS_RE6 - const byte = 0b00100_110
PPS_RE7 - const byte = 0b00100_111
PPS_RF0 - const byte = 0b00101_000
PPS_RF1 - const byte = 0b00101_001
PPS_RF2 - const byte = 0b00101_010
PPS_RF3 - const byte = 0b00101_011
PPS_RF4 - const byte = 0b00101_100
PPS_RF5 - const byte = 0b00101_101
PPS_RF6 - const byte = 0b00101_110
PPS_RF7 - const byte = 0b00101_111
PPS_RG0 - const byte = 0b00110_000
PPS_RG1 - const byte = 0b00110_001
PPS_RG2 - const byte = 0b00110_010
PPS_RG3 - const byte = 0b00110_011
PPS_RG4 - const byte = 0b00110_100
PPS_RG5 - const byte = 0b00110_101
PPS_RG6 - const byte = 0b00110_110
PPS_RG7 - const byte = 0b00110_111
PPS_RH0 - const byte = 0b00111_000
PPS_RH1 - const byte = 0b00111_001
PPS_RH2 - const byte = 0b00111_010
PPS_RH3 - const byte = 0b00111_011
PPS_RH4 - const byte = 0b00111_100
PPS_RH5 - const byte = 0b00111_101
PPS_RH6 - const byte = 0b00111_110
PPS_RH7 - const byte = 0b00111_111

Routines

  • pps_control_lock - Procedure


pps_control_lock - JALlib Procedures Help

pps_control_lock JALLIB PROCEDURE

Signature

procedure pps_control_lock(bit in state) is

Description

Title: Unlock/Lock the PPS module.
Input: Desired PPS lock state (bit: TRUE == locked, FALSE == unlocked)
Returns: (nothing)
Notes: - Applies to all PPS-groups, differences are taken care of.
- Interrupts are disabled during the unlocked state.

Include

To use this procedure, include the library:

include pps

Parameters

  • state - bit in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: pps.jal


PRAGMA - JAL Language Syntax Reference

PRAGMA JALV2 SYNTAX

Syntax

PRAGMA INTERRUPT [FAST]
PRAGMA TASK
PRAGMA KEEP PAGE
PRAGMA KEEP BANK
PRAGMA TARGET CLOCK frequency

Description

Compiler directives that provide special instructions to the compiler.

Notes

FAST interrupts have higher priority on processors that support it.

Example

PROCEDURE my_interrupt IS
PRAGMA INTERRUPT
    -- interrupt code
END PROCEDURE

Generated by JAL Syntax Documentation System | Source: DITA


print.jal - JALLIB Library Documentation

print.jal JALLIB LIBRARY

Title

Writes variables to output device

Author

Oliver "Kiste" Seitz, Copyright (c) 2011..2025, all rights reserved., Adapted-by: Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

.
Prints variables to output device, typically an lcd or a serial port
Input variables: bit, byte, sbyte, word, sword, dword, sdword, float
Output formats: decimal, hexadecimal, binary and some specials
.
For decimal output an arbitrary variable size supported.
The user may define a constant with a positive value greater than one.
const PRINT_MAX_VAR_SIZE
before including this library to specify the highest variable size
is required for his program.
When not specified by the user a default of 4 is used, which means
variables upto dword or sdword are supported.
.
Examples:
.
var sword bhl = -684
.
Print the signed word in decimal notation on an LCD
print_sword_dec(lcd, bhl)
will send "-684" to device 'lcd'
.
To send the same signed word to a serial port:
print_sword_dec(serial_hw_data, bhl)
.
Specials:
print_crlf(serial_hw_data) will send CR + LF to the device 'serial_hw_data'.
.
const byte str1[] = "JalLibWorld V1.0"
print_string(lcd, str1) will display the string 'str' on an lcd.
.
. Note - the whole string - that is the length of the array -
. is printed. When you use a variable array to construct strings,
. you might want to terminate at a termination character like 0x00.
. You can set this termination character with:
. const byte print_string_terminator = 0x00
. (or use a var if you want to change it at runtime.)

Notes

.
- This library replaces an older version which had no scalability.
It should be compatible with the old library except for:
* All procedures for binary output have been renamed to
print_xxxx_bin() for name consistency with '_dec' and '_hex'.
* print_bit_truefalse() has been renamed to print_bit_logic()
* print_bit_highlow() has been renamed to print_bit_level()
* print_bit_10() has been renamed to print_bit_bin()
* For renamed procedures a procedure issuing a deprecation
warning is provided for compatibility.
* The procedure print_sword_fp_dec() has been dropped.
For output of fixed point numbers use the format library.
* Some procedures are added to print signed bytes, words and double
words in binary and hexadecimal format (without sign!).
---------------------------------------------------------------------------

Constant to define the maximum supported variable size (in bytes)
to be supported by this library.

Constants and Variables

print_prefix - var bit = FALSE -- default: no '0x' or '0b' prefixes
default: no '0x' or '0b' prefixes

Routines

  • _make_tenfold_divisor - Procedure
  • nibble2hex - Function returns byte
  • print_bit_10 - Procedure
  • print_bit_bin - Procedure
  • print_bit_highlow - Procedure
  • print_bit_level - Procedure
  • print_bit_logic - Procedure
  • print_bit_truefalse - Procedure
  • print_byte_bin - Procedure
  • print_byte_binary - Procedure
  • print_byte_dec - Procedure
  • print_byte_hex - Procedure
  • print_cls_ansi - Procedure
  • print_crlf - Procedure
  • print_dword_bin - Procedure
  • print_dword_binary - Procedure
  • print_dword_dec - Procedure
  • print_dword_hex - Procedure
  • print_float - Procedure
  • print_maxsvar_dec - Procedure
  • print_maxvar_dec - Procedure
  • print_nibble_bin - Procedure
  • print_nibble_binary - Procedure
  • print_sbyte_bin - Procedure
  • print_sbyte_dec - Procedure
  • print_sbyte_hex - Procedure
  • print_sdword_bin - Procedure
  • print_sdword_dec - Procedure
  • print_sdword_hex - Procedure
  • print_string - Procedure
  • print_sword_bin - Procedure
  • print_sword_dec - Procedure
  • print_sword_hex - Procedure
  • print_word_bin - Procedure
  • print_word_binary - Procedure
  • print_word_dec - Procedure
  • print_word_hex - Procedure


print_bit_bin - JALlib Procedures Help

print_bit_bin JALLIB PROCEDURE

Signature

procedure print_bit_bin(volatile byte out device, bit in data) is

Description

Title: Print binary value of a bit
Arguments: - device name
- bit
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - bit in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_bit_level - JALlib Procedures Help

print_bit_level JALLIB PROCEDURE

Signature

procedure print_bit_level(volatile byte out device, bit in data) is

Description

Title: Print voltage level of a bit
Arguments: - device name
- bit
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - bit in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_bit_logic - JALlib Procedures Help

print_bit_logic JALLIB PROCEDURE

Signature

procedure print_bit_logic(volatile byte out device, bit in data) is

Description

Title: Print logical value of a bit
Arguments: - device name
- bit
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - bit in

Return Value

None

Example

From sample file: 16f877_i2c_sw_l1.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for i2c_software.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Level 0 i2c test program
--    interact with an i2c eeprom using the i2c primitives
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    setup:
--         an 24lc256 i2c eeprom, connected to the test board i2c pins.
--         a serial connection to a terminal
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_i2c_sw_l1.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
enable_digital_io()                -- make all pins digital I/O
;@jallib section i2c
-- I2C io definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction

-- generic setup (see releated examples for more details)
;@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include print
include delay

-- i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB;  i2c_hw only)

;include i2c_hardware
include i2c_software

i2c_initialize()

var byte i2c_tx_buffer[10]
var byte i2c_rx_buffer[10]

include i2c_level1

-- we're alive
const byte str1[] = "Test.\r\n"
print_string(serial_hw_data, str1)

var bit r
var byte i

forever loop

   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
;   i2c_tx_buffer[0] = 0x12  -- high byte address within i2c eeprom
;   i2c_tx_buffer[1] = 0x34  -- low byte address within i2c eeprom
;   r = i2c_send_receive(0xA0, 2, 3)

   -- same as above
   -- Send 2 bytes address to device 0xA0 and
   -- then read 3 bytes of data
   r = i2c_receive_wordaddr(0xA0, 0x0000, 3)

   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_byte_hex(serial_hw_data, i2c_rx_buffer[0]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[1]);
   serial_hw_data = " "
   print_byte_hex(serial_hw_data, i2c_rx_buffer[2]);
   serial_hw_data = " "

   -- write part (increment 3rd byte at 0x0002)
   i2c_tx_buffer[0] = 0x12     -- high byte addr within i2c eeprom
   i2c_tx_buffer[1] = 0x34 + 2 -- low byte addr within i2c eeprom
   i2c_tx_buffer[2] = i2c_rx_buffer[2] + 1  -- data
   r = i2c_send_receive(0xA0, 3, 0)
   print_bit_logic(serial_hw_data, r)
   serial_hw_data = " "

   print_crlf(serial_hw_data)

   delay_100ms(10)
end loop

Generated by JALlib CHM Help System | Source: print.jal


print_byte_bin - JALlib Procedures Help

print_byte_bin JALLIB PROCEDURE

Signature

procedure print_byte_bin(volatile byte out device, byte in data) is

Description

Title: Print unsigned byte binary
Arguments: - device name
- byte
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - byte in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_byte_dec - JALlib Procedures Help

print_byte_dec JALLIB PROCEDURE

Signature

procedure print_byte_dec(volatile byte out device, byte in data) is

Description

Title: Print unsigned byte decimal
Arguments: - device name
- byte
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - byte in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_byte_hex - JALlib Procedures Help

print_byte_hex JALLIB PROCEDURE

Signature

procedure print_byte_hex(volatile byte out device, byte in data) is

Description

Title: Print unsigned byte hexadecimal
Arguments: - device name
- byte
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - byte in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


print_crlf - JALlib Procedures Help

print_crlf JALLIB PROCEDURE

Signature

procedure print_crlf(volatile byte out device) is

Description

Title: Print Carriage Return + LineFeed
Arguments: - device name
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


print_dword_bin - JALlib Procedures Help

print_dword_bin JALLIB PROCEDURE

Signature

procedure print_dword_bin(volatile byte out device, dword in data) is

Description

Title: Print unsigned double word binary
Arguments: - device name
- dword (byte*4 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - dword in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_dword_dec - JALlib Procedures Help

print_dword_dec JALLIB PROCEDURE

Signature

procedure print_dword_dec(volatile byte out device, dword in data) is

Description

Title: Print unsigned double word decimal
Arguments: - device name
- dword (byte*4 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - dword in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


print_dword_hex - JALlib Procedures Help

print_dword_hex JALLIB PROCEDURE

Signature

procedure print_dword_hex(volatile byte out device, dword in data) is

Description

Title: Print unsigned double word hexadecimal
Arguments: - device name
- dword (byte*4 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - dword in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


print_float - JALlib Procedures Help

print_float JALLIB PROCEDURE

Signature

procedure print_float(volatile byte out device, float in data) is

Description

Title: Print float
Arguments: - device name
- float
Returns: nothing
Note: results in [-]#.#######e[-]##
Based on float to ascii in 'funcs'

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - float in

Return Value

None

Example

From sample file: 16f1825_ina3221.jal

-----------------------------------------------------------------------------
-- Title: Sample and test program INA3221 Triple Channel Shunt and Bus Voltage Monitor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the INA3221 Triple
--              Channel Shunt and Bus Voltage Monitor including alert.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              There are two ways to use the ina3221 library, with floats or
--              without floats where it uses word/dword (default). Details are
--              given in the ian3221 library. To use floats define:
--              -) Const INA3221_USE_FLOAT = TRUE
--
-- Sources: Datasheet Texas Instruments INA3221 Triple-Channel, High-Side
--          Measurement, Shunt and Bus Voltage Monitor with I2C- and
--          SMBUS-Compatible interface. SBOS576B –MAY 2012–REVISED MARCH 2016
--
-- Notes:   Channels are numbered 1..3, but values 0..2 are used.
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()

-- Now include the ina3221 library and initialize.
-- Remove the comment below if you want to use floats instead of word/dword.
-- const INA3221_USE_FLOAT = TRUE
include ina3221
ina3221_init()

-- ------------------------------ Variables ---------------------------------
if defined(INA3221_USE_FLOAT) then
   var float voltage -- In Volt
   var float current -- In Ampere
else
   var word bus_voltage   -- In mV
   var sdword shunt_voltage -- In uV
   var sdword current      -- In uA
end if

var word flags
var byte channel
-- ------------------------------ Main program ---------------------------------
print_string(serial, "Sample program for the INA3221 Triple Channel Shunt and Bus Voltage Monitor.\r\n\n")

-- The default IIC address is set to INA3221_IIC_DEFAULT_ADDRESS which is
-- A0 connected to GND which is address 0x40. If A0 is connected to VCC  the
-- address can be changed by using:
-- ina3321_set_iic_address(0x41)

-- Set alerts on channel 1 and 3. Change to your specific volltage
if defined(INA3221_USE_FLOAT) then
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18.5E-3)
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3.0E-3)
else
   print_string(serial, "Setting shunt voltage warning alert limit for channel 2 to +18.5 mV.\r\n")
   ina3221_set_warning_alert_limit(INA3221_CHANNEL_2, 18_500) -- uV
   print_string(serial, "Setting shunt voltage critical alert limit for channel 3 to -3 mV.\r\n\n")
   ina3221_set_critical_alert_limit(INA3221_CHANNEL_3, -3_000) -- uV
end if

forever loop

   for INA3221_NR_OF_CHANNELS using channel loop
      if defined(INA3221_USE_FLOAT) then
         -- Version using floats.

         -- Get bus voltage.
         voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (V): ")
            print_float(serial, voltage)
            print_crlf(serial)
         end if

         -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (A): ")
            print_float(serial, current)
            print_crlf(serial)
         end if

      else
         -- Version using word/dword, combined with float.

         -- Get bus voltage.
         bus_voltage = ina3221_get_bus_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The bus voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (mV):  ")
            print_word_dec(serial, bus_voltage)
            print_crlf(serial)
         end if

         -- Get shunt voltage.
         shunt_voltage = ina3221_get_shunt_voltage(channel)
         -- Using the timeout function is optional.
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The shunt voltage on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uV):  ")
            print_sdword_dec(serial, shunt_voltage)
            print_crlf(serial)
         end if

          -- Get Current.
         current = ina3221_get_current(channel)
         if ina3221_timeout_occured() then
            print_string(serial, "IIC bus timeout occured.\r\n ")
         else
            print_string(serial, "The current on channel ")
            print_byte_dec(serial, channel + 1) -- Module uses channel names 1..3.
            print_string(serial, " is (uA):  ")
            print_sdword_dec(serial, current)
            print_crlf(serial)
         end if

      end if

   end loop

   ; Check for alerts.
   flags = ina3221_get_flags()
   for INA3221_NR_OF_CHANNELS using channel loop
      if ina3221_critical_alert(flags, channel) then
         print_string(serial, "Critical Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
      if ina3221_warning_alert(flags, channel) then
         print_string(serial, "Warning Alert on channel:")
         print_byte_dec(serial, channel + 1)
         print_crlf(serial)
      end if
   end loop
   print_crlf(serial)

   _usec_delay(1_000_000)

end loop

Generated by JALlib CHM Help System | Source: print.jal


print_maxvar_dec - JALlib Procedures Help

print_maxvar_dec JALLIB PROCEDURE

Signature

procedure print_maxvar_dec(volatile byte out device, byte*PRINT_MAX_VAR_SIZE in data) is

Description

Title: Print unsigned decimal value
Arguments: - device name
- decimal variable (byte*PRINT_MAX_VAR_SIZE variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - byte*PRINT_MAX_VAR_SIZE in

Return Value

None

Example

From sample file: 18f2520_print_large_number.jal

-- ------------------------------------------------------
-- Title:  test file for printing large numbers
--
-- Author: Oliver "Kiste" Seitz
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Demo program for print.jal library using Microchip PIC12f615.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_print_large_number.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog

enable_digital_io()                -- make all pins digital I/O

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

serial_hw_init()

alias serial_data is serial_hw_data

const VAR_SIZE=32       -- set the maximum variable size

const PRINT_MAX_VAR_SIZE=VAR_SIZE   -- use this size also for print.jal

include print

include delay

delay_1s(5)          -- some seconds initial delay to move eyes from power plug to computer screen ;-)

var byte*VAR_SIZE runner      -- this variable holds the results of the computations

var byte*VAR_SIZE carry       -- some auxiliary variable

var word counter

var bit overflow

const byte title11[]="The largest printable number=\r\n2^"

print_string(serial_data,title11)

print_word_dec(serial_data,8*VAR_SIZE)

serial_data="-"
serial_data="1"
serial_data="="

runner=0
runner=runner-1

print_maxvar_dec(serial_data,runner)
print_crlf(serial_data)
print_crlf(serial_data)

overflow=false
runner=1
counter=0

const byte title1[]="Factorials:"
print_string(serial_data,title1) -- print a nice header
print_crlf(serial_data)

repeat

  print_word_dec(serial_data,counter)
  serial_data="!"
  serial_data="="
  print_maxvar_dec(serial_data,runner)
  print_crlf(serial_data)

         -- 0! = 1 ; n! = (n-1)! * n
         -- We do not use multiplication here, as it uses way more ram than additions.
         -- Besides, overflow detection is easy and cheap when only using additions.
         -- Execution time is no real problem, as the loop will not repeat very often,
         -- 70! (=2485 loop runs altogether) will already result in more than 100 decimal digits.

  carry=runner
  for counter loop
    runner=runner+carry
    if runner<=carry then
      overflow=true
    end if
  end loop
  counter=counter+1

until overflow

print_crlf(serial_data)

const byte title2[]="Powers of two:"
print_string(serial_data,title2) -- print a nice header
print_crlf(serial_data)

counter=0
runner=1

repeat
  serial_data="2"
  serial_data="^"
  print_word_dec(serial_data,counter)
  serial_data="="
  print_maxvar_dec(serial_data,runner)
  print_crlf(serial_data)

  counter=counter+1
  runner=runner<<1

until runner==0

const byte title3[]="That's it!"
print_string(serial_data,title3) -- say goodbye
print_crlf(serial_data)
print_crlf(serial_data)
delay_1ms(3)            -- wait for the last 2 bytes to be transmitted
asm sleep            -- switch off :-)

forever loop
end loop
--

Generated by JALlib CHM Help System | Source: print.jal


print_sbyte_dec - JALlib Procedures Help

print_sbyte_dec JALLIB PROCEDURE

Signature

procedure print_sbyte_dec(volatile byte out device, sbyte in data) is

Description

Title: Print unsigned byte decimal
Arguments: - device name
- byte
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - sbyte in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_sdword_dec - JALlib Procedures Help

print_sdword_dec JALLIB PROCEDURE

Signature

procedure print_sdword_dec(volatile byte out device, sdword in data) is

Description

Title: Print signed double word decimal
Arguments: - device name
- sdword (sbyte*4 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - sdword in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_string - JALlib Procedures Help

print_string JALLIB PROCEDURE

Signature

procedure print_string(volatile byte out device, byte in str[]) is

Description

Title: Print string
Arguments: - device name
- string (array of bytes)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • str[] - byte in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


print_sword_dec - JALlib Procedures Help

print_sword_dec JALLIB PROCEDURE

Signature

procedure print_sword_dec(volatile byte out device, sword in data) is

Description

Title: Print signed word decimal
Arguments: - device name
- sword (sbyte*2 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - sword in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_udp_socket_info - JALlib Procedures Help

print_udp_socket_info JALLIB PROCEDURE

Signature

procedure print_udp_socket_info(bit in receiving_sending, byte in socket) is

Description

print info about a socket

Include

To use this procedure, include the library:

include udp

Parameters

  • receiving_sending - bit in
  • socket - byte in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: udp.jal


print_word_bin - JALlib Procedures Help

print_word_bin JALLIB PROCEDURE

Signature

procedure print_word_bin(volatile byte out device, word in data) is

Description

Title: Print unsigned word binary
Arguments: - device name
- word (byte*2 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - word in

Return Value

None

Example

From sample file: 16f877_serial_print.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for print.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_serial_print.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include format
include print

led_direction = output

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   --
   -- The print_* and format_* routines assing the output chars to this pseudo-var.
   --

   -- output the string, the pseudo var is the first param.
   const byte str1[] = " - Test print.jal- bytes\r\n"   -- define a string
   print_string(serial_hw_data, str1)                 -- output string
--   print_string(serial_hw_data, " - Test print.jal- bytes\r\n") -- output string (not yet supported by JAL)

   -- -----------
   -- byte stuff
   -- -----------
   var  byte a =  210
   var sbyte b = -109

   print_byte_dec(serial_hw_data, a)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_byte_hex(serial_hw_data, a)   -- output in hex format
   print_crlf(serial_hw_data)
   print_byte_bin(serial_hw_data, a)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sbyte_dec(serial_hw_data, b)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- word stuff
   -- -----------
   const byte str2[] = "Test print.jal - words\r\n"   -- define a string
   print_string(serial_hw_data, str2)

   var  word c =  45678
   var sword d = -32109

   print_word_dec(serial_hw_data, c)   -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_word_hex(serial_hw_data, c)   -- output in hex format
   print_crlf(serial_hw_data)
   print_word_bin(serial_hw_data, c)   -- output in binary format
   print_crlf(serial_hw_data)

   print_sword_dec(serial_hw_data, d)  -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- dword stuff
   -- -----------
   const byte str3[] = "Test print.jal - dwords\r\n"   -- define a string
   print_string(serial_hw_data, str3)

   var  dword e =  3210987654
   var sdword f = -2109876543

   print_dword_dec(serial_hw_data, e)  -- output in (unsigned) decimal format
   print_crlf(serial_hw_data)          -- output Carriage Return and Linefeed (0x0D 0x0A), new line
   print_dword_hex(serial_hw_data, e)  -- output in hex format
   print_crlf(serial_hw_data)
   print_dword_bin(serial_hw_data, e)  -- output in binary format
   print_crlf(serial_hw_data)

   print_sdword_dec(serial_hw_data, f)   -- output in signed decimal format
   print_crlf(serial_hw_data)

   -- -----------
   -- bit stuff
   -- -----------
   const byte str4[] = "Test print.jal - bit\r\n"   -- define a string
   print_string(serial_hw_data, str4)

   var bit g = 1

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'
   serial_hw_data = " "                      -- output a space

   g = 0

   print_bit_bin(serial_hw_data, g)           -- output 0 or 1
   serial_hw_data = " "                      -- output a space

   print_bit_level(serial_hw_data, g)      -- output text 'high' or 'low'
   serial_hw_data = " "                      -- output a space

   print_bit_logic(serial_hw_data, g)    -- output text 'true' or 'false'

   print_crlf(serial_hw_data)

   -- -------------
   -- and together:
   -- -------------

   var byte x = "y"
   const byte str5[] = "Variable x has decimal value "
   print_string(serial_hw_data, str5)
   print_byte_dec(serial_hw_data, x)

   const byte str6[] = " which is hex value "
   print_string(serial_hw_data, str6)
   print_byte_hex(serial_hw_data, x)

   const byte str7[] = " and represents ASCII character "
   print_string(serial_hw_data, str7)
   serial_hw_data = x

   print_crlf(serial_hw_data)
   print_crlf(serial_hw_data)

end loop

-- A - Test print.jal- bytes
-- 210
-- D2
-- 11010010
-- -109
-- Test print.jal - words
-- 45678
-- B26E
-- 1011001001101110
-- -32109
-- Test print.jal - dwords
-- 3210987654
-- BF63C886
-- 10111111011000111100100010000110
-- -2109876543
-- Test print.jal - bit
-- 1 high true 0 low false
-- Variable x has decimal value 121 which is hex value 79 and represents ASCII character y

Generated by JALlib CHM Help System | Source: print.jal


print_word_dec - JALlib Procedures Help

print_word_dec JALLIB PROCEDURE

Signature

procedure print_word_dec(volatile byte out device, word in data) is

Description

Title: Print unsigned word decimal
Arguments: - device name
- word (byte*2 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - word in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


print_word_hex - JALlib Procedures Help

print_word_hex JALLIB PROCEDURE

Signature

procedure print_word_hex(volatile byte out device, word in data) is

Description

Title: Print unsigned word hexadecimal
Arguments: - device name
- word (byte*2 variable)
Returns: nothing

Include

To use this procedure, include the library:

include print

Parameters

  • device - byte out
  • data - word in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: print.jal


Sub-programs: Procedures and Functions - JAL Language Syntax Reference

Sub-programs: Procedures and Functions JALV2 SYNTAX

Syntax

PROCEDURE identifier
    [ '('
        [ VOLATILE ]
        type { IN | OUT | IN OUT } identifier
        [ ',' type { IN | OUT | IN OUT } identifier ... ]
      ')'
    ]
    IS
    statement_block
END PROCEDURE
FUNCTION identifier
    [ '('
        [ VOLATILE ]
        type { IN | OUT | IN OUT } identifier
        [ ',' type { IN | OUT | IN OUT } identifier ... ]
      ')'
    ]
    RETURN type
    IS
    statement_block
END FUNCTION

Description

The only difference between a PROCEDURE and a FUNCTION, is the former
does not return a value, while the later does. The procedure

When executed, the sub program immediately returns. If the sub program
is a FUNCTION,
A sub-program is executed simply by using its name. If parameters are
specified in the sub-program definition, all parameters are required,
otherwise none are allowed. A FUNCTION can be used anywhere a value is
required (in expressions, as parameters to other sub-programs, etc). There
is no limit to the number of parameters. JALv2 is a pass by value language. Conceptually, an IN parameter is
read once when the sub-program enters, and an OUT parameter is written
once when the sub-program returns. This is not always desired. For example
if a sub-program writes a string of characters to the serial port (passed
as parameter), only the last character written will be sent. For this case
we need VOLATILE parameters. These are either read each time used (IN) or
written each time assigned (OUT). This is accomplished using pseudo
variables (see below). If the value passed is not a pseudo-variable, a
suitable one is created. There are two ways to pass an array into a sub-program: The first follows the pass-by-value semantics noted above. An array
variable of size 5, str, is allocated in the namespace of the procedure.
Any callers must call with an array of exactly 5 bytes, which is copied
into the local variable and used. Alternately, the second version created a flexible array. This is
pass-by-reference which means (1) the amount of data space used for str is
only two or three bytes, and (2) any sized array can be passed in. This is
generally far more useful, and far less wasteful. The operator COUNT can
be used to determine the size of the array passed in. Procedures and functions can be nested. Recursion is fully supported but due to the overhead it is
discouraged.
                  RETURN [

          PROCEDURE string_write (BYTE IN str[5]) IS...
          PROCEDURE string_write (BYTE IN str[]) IS...

Example

          FUNCTION square_root (WORD IN n) RETURN WORD IS
             WORD result
             WORD ix
             ix = 1
             WHILE ix < n LOOP
                n = n - ix
                result = result + 1
                ix = ix + 2
             END LOOP
             RETURN result
          END FUNCTION
          xx = square_root(xx)

Generated by JAL Syntax Documentation System | Source: DITA


profiler.jal - JALLIB Library Documentation

profiler.jal JALLIB LIBRARY

Title

profiler.jal

Author

Joep Suijs, Copyright (c) 2009..2009, all rights reserved., Adapted-by:

Compiler

>=2.4g

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides procedures to profile code parts.
Intended for software development, uses timer1.
-----------------------------------------------------------------------------

Routines

  • profiler_report - Procedure
  • profiler_setup - Procedure
  • profiler_start - Procedure
  • profiler_stop - Procedure
  • profiler_stop_and_report - Procedure


profiler_setup - JALlib Procedures Help

profiler_setup JALLIB PROCEDURE

Signature

procedure profiler_setup(byte in resolution) is

Description

This library provides procedures to profile code parts.
Intended for software development, uses timer1.

Include

To use this procedure, include the library:

include profiler

Parameters

  • resolution - byte in

Return Value

None

Example

From sample file: 18f4550_sqrt.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for sqrt.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_sqrt.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog
;@jallib section led
-- LED IO definition
alias led is pin_b3
alias led_direction is pin_b3_direction
alias led2 is pin_b1
alias led2_direction is pin_b1_direction

include delay
include print

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include profiler

include math

led_direction = output

var word r

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   profiler_setup(0)

   profiler_start()
   r = sqrt32(65535*65533)
   profiler_stop_and_report(serial_hw_data)

   print_word_dec(serial_hw_data, r)

end loop

Generated by JALlib CHM Help System | Source: profiler.jal


profiler_start - JALlib Procedures Help

profiler_start JALLIB PROCEDURE

Signature

procedure profiler_start() is

Description

This library provides procedures to profile code parts.
Intended for software development, uses timer1.

Include

To use this procedure, include the library:

include profiler

Parameters

None

Return Value

None

Example

From sample file: 18f4550_sqrt.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for sqrt.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_sqrt.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog
;@jallib section led
-- LED IO definition
alias led is pin_b3
alias led_direction is pin_b3_direction
alias led2 is pin_b1
alias led2_direction is pin_b1_direction

include delay
include print

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include profiler

include math

led_direction = output

var word r

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   profiler_setup(0)

   profiler_start()
   r = sqrt32(65535*65533)
   profiler_stop_and_report(serial_hw_data)

   print_word_dec(serial_hw_data, r)

end loop

Generated by JALlib CHM Help System | Source: profiler.jal


profiler_stop_and_report - JALlib Procedures Help

profiler_stop_and_report JALLIB PROCEDURE

Signature

procedure profiler_stop_and_report(volatile byte in out device) is

Description

This library provides procedures to profile code parts.
Intended for software development, uses timer1.

Include

To use this procedure, include the library:

include profiler

Parameters

  • device - byte in out

Return Value

None

Example

From sample file: 18f4550_sqrt.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for sqrt.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_sqrt.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog
;@jallib section led
-- LED IO definition
alias led is pin_b3
alias led_direction is pin_b3_direction
alias led2 is pin_b1
alias led2_direction is pin_b1_direction

include delay
include print

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include profiler

include math

led_direction = output

var word r

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   profiler_setup(0)

   profiler_start()
   r = sqrt32(65535*65533)
   profiler_stop_and_report(serial_hw_data)

   print_word_dec(serial_hw_data, r)

end loop

Generated by JALlib CHM Help System | Source: profiler.jal


ps2.jal - JALLIB Library Documentation

ps2.jal JALLIB LIBRARY

Title

PS2 library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library allows a user to read data from a PS2 Keyboard.

Sources

http://www.computer-engineering.org/ps2protocol/
http://www.computer-engineering.org/ps2keyboard/scancodes2.html
Note: 10k pull-up resistor on clock & data line.

Constants and Variables

PS2_F9 - const byte = 0x1 --
PS2_F5 - const byte = 0x3 --
PS2_F3 - const byte = 0x4 --
PS2_F1 - const byte = 0x5 --
PS2_F2 - const byte = 0x6 --
PS2_F12 - const byte = 0x7 --
PS2_F10 - const byte = 0x9 --
PS2_F8 - const byte = 0x0A --
PS2_F6 - const byte = 0x0B --
PS2_F4 - const byte = 0x0C --
PS2_L_ALT - const byte = 0x11 --
PS2_L_SHIFT - const byte = 0x12 --
PS2_L_CTRL - const byte = 0x14 --
PS2_CAPS - const byte = 0x58 --
PS2_R_SHIFT - const byte = 0x59 --
PS2_ENTER - const byte = 0x5A --
PS2_BACKSPACE - const byte = 0x66 --
PS2_KP_1 - const byte = 0x69 --
PS2_KP_4 - const byte = 0x6B --
PS2_KP7 - const byte = 0x6C --
PS2_KP0 - const byte = 0x70 --
PS2_KP_PERIOD - const byte = 0x71 --
PS2_KP2 - const byte = 0x72 --
PS2_KP5 - const byte = 0x73 --
PS2_KP6 - const byte = 0x74 --
PS2_KP8 - const byte = 0x75 --
PS2_ESC - const byte = 0x76 --
PS2_NUM_LOCK - const byte = 0x77 --
PS2_F11 - const byte = 0x78 --
PS2_KP_PLUS - const byte = 0x79 --
PS2_KP3 - const byte = 0x7A --
PS2_KP_MINUS - const byte = 0x7B --
PS2_KP_ASTRISK - const byte = 0x7C --
PS2_KP9 - const byte = 0x7D --
PS2_SCROLL - const byte = 0x7E --
PS2_F7 - const byte = 0x83 --

Routines

  • _ps2_read_bit - Function returns bit
  • ps2_read_byte - Function returns byte


ps2_read_byte - JALlib Procedures Help

ps2_read_byte JALLIB FUNCTION

Signature

function ps2_read_byte() return byte is

Description

Waits for a byte to be received via PS2

Include

To use this procedure, include the library:

include ps2

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f4620_ps2_keyboard.jal

-- Title: PS2 Keyboard Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows a user to send characters to the serial port
--              via a PS2 Keyboard. This sample only implements most used
--              buttons, but more can be added.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.computer-engineering.org/ps2protocol/
-- http://www.computer-engineering.org/ps2keyboard/
-- http://www.computer-engineering.org/ps2keyboard/scancodes2.html
--
-- Note: 10k pull-up resistor on clock line.
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT  -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- PS2
alias pin_clock is pin_sck
alias pin_clock_direction is pin_sck_direction
pin_clock_direction = input

alias pin_data is pin_sdi
alias pin_data_direction is pin_sdi_direction
pin_data_direction = input
--
include ps2

-- main program

-- setup vars
var byte button_used[4] = {0,0,1,0}
const byte IS_SPECIAL  = 3
const byte IS_CAPITAL  = 2
const byte PRESSED  = 1
const byte CHAR = 0
var bit shift_down = FALSE

-- Gets code corresponding to button pressed.
procedure ps2_read_button() is
   var byte data = ps2_read_byte()

   if data == 0xF0 then -- button up
      button_used[PRESSED] = FALSE
      ps2_read_button() -- read next char
   elsif button_used[PRESSED] == FALSE then
      if data == ps2_lookup_table[data] then
         button_used[IS_SPECIAL] = TRUE
      end if
      button_used[CHAR] = ps2_lookup_table[data]
   elsif data != ps2_lookup_table[data] then   -- if
      button_used[IS_SPECIAL] = FALSE
      button_used[CHAR] = ps2_lookup_table[data]
   else
      -- special character
      button_used[IS_SPECIAL] = TRUE
      button_used[CHAR] = data
   end if
end procedure

-- main loop
forever loop
   -- read a button
   ps2_read_button()

   -- if button pressed
   if button_used[PRESSED] == TRUE then
      if button_used[IS_SPECIAL] == TRUE then
         if button_used[CHAR] == PS2_ENTER then
            print_crlf(serial_data)
         elsif (button_used[CHAR] == PS2_R_SHIFT) | (button_used[CHAR] == PS2_L_SHIFT) then
            shift_down = TRUE
         end if
      else
         if shift_down == FALSE then
            serial_data = button_used[CHAR]
         else
             serial_data = button_used[CHAR] - 32
         end if
      end if

   else -- if button un-pressed

      -- check if it is a special character
      if button_used[IS_SPECIAL] == TRUE then
         if (button_used[CHAR] == PS2_R_SHIFT) | (button_used[CHAR] == PS2_L_SHIFT) then
            shift_down = FALSE
         end if
      end if

      button_used[PRESSED] = TRUE
   end if

end loop

Generated by JALlib CHM Help System | Source: ps2.jal


ps_adjust_period - JALlib Procedures Help

ps_adjust_period JALLIB PROCEDURE

Signature

procedure ps_adjust_period() is

Description

No description available.

Include

To use this procedure, include the library:

include period_skip

Parameters

None

Return Value

None

Example

From sample file: 16f877_period_skip.jal

-- Title: motor speed control by skipping periods of AC mains
-- Author: Eur van Andel, eur@fiwihex.nl (c) 2009
-- Compiler: >=2.4g
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: AC induction motors are low-priced, very reliable and widely available.
-- They are often used for pumps and fans. They are hard to control, mostly with expensive
-- frequency converters. This application shows how to fine-tune the speed of such a motor,
-- up from 0 RPM to 99.6% of full speed, without the electrical noise of phase control and
-- without large duty cycles of varying speed.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f877

pragma target clock 20_000_000  -- 20 MHz xtal
pragma target OSC       HS
pragma target WDT       disabled        -- no watchdog, please
pragma target LVP       enabled         -- allow low voltage programming, frees up pin_b3

-- set all IO as digital
enable_digital_io()

var bit triac is pin_c1 = off    -- pin connected to optotriac, can be any output
pin_c1_direction = output
pin_b0_direction = input   -- must be interrupt pin, connected to zero-crossing signal

var byte ps_speed = 0         -- 0..255 speed control

include period_skip        -- library, read for explanation and schematics

include delay

-- start of main program

forever loop
   for 20 loop          -- two seconds, motor needs time to adjust to new speed
      delay_100ms(1)
      ps_check_period()    -- call at least every 320ms for 50Hz, 267ms for 60Hz
   end loop
   ps_speed = ps_speed + 10
   ps_adjust_period()      -- call when speed changes
end loop    -- end of main loop

Generated by JALlib CHM Help System | Source: period_skip.jal


ps_check_period - JALlib Procedures Help

ps_check_period JALLIB PROCEDURE

Signature

procedure ps_check_period() is -- should be called every 320 ms @ 50 Hz!

Description

No description available.

Include

To use this procedure, include the library:

include period_skip

Parameters

None

Return Value

None

Example

From sample file: 16f877_period_skip.jal

-- Title: motor speed control by skipping periods of AC mains
-- Author: Eur van Andel, eur@fiwihex.nl (c) 2009
-- Compiler: >=2.4g
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: AC induction motors are low-priced, very reliable and widely available.
-- They are often used for pumps and fans. They are hard to control, mostly with expensive
-- frequency converters. This application shows how to fine-tune the speed of such a motor,
-- up from 0 RPM to 99.6% of full speed, without the electrical noise of phase control and
-- without large duty cycles of varying speed.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f877

pragma target clock 20_000_000  -- 20 MHz xtal
pragma target OSC       HS
pragma target WDT       disabled        -- no watchdog, please
pragma target LVP       enabled         -- allow low voltage programming, frees up pin_b3

-- set all IO as digital
enable_digital_io()

var bit triac is pin_c1 = off    -- pin connected to optotriac, can be any output
pin_c1_direction = output
pin_b0_direction = input   -- must be interrupt pin, connected to zero-crossing signal

var byte ps_speed = 0         -- 0..255 speed control

include period_skip        -- library, read for explanation and schematics

include delay

-- start of main program

forever loop
   for 20 loop          -- two seconds, motor needs time to adjust to new speed
      delay_100ms(1)
      ps_check_period()    -- call at least every 320ms for 50Hz, 267ms for 60Hz
   end loop
   ps_speed = ps_speed + 10
   ps_adjust_period()      -- call when speed changes
end loop    -- end of main loop

Generated by JALlib CHM Help System | Source: period_skip.jal


Pseudo-variables - JAL Language Syntax Reference

Pseudo-variables JALV2 SYNTAX

Syntax

PROCEDURE FUNCTION

Description

A pseudo-variable is a sub-program, or pair of sub-programs that work as if they are variables. If a 'PUT procedure is defined, any assignment to If both a 'GET and 'PUT sub-program are defined, the parameter type of the 'PUT must match the return type of the 'GET.

Example

          FUNCTION pin'GET() RETURN BIT IS
             return pin_shadow
          END FUNCTION
          PROCEDURE pin'PUT(BIT in xx) IS
             pin_shadow = xx
             port = port_shadow
          END PROCEDURE
          pin = 5

Generated by JAL Syntax Documentation System | Source: DITA


pwm1_max_resolution - JALlib Procedures Help

pwm1_max_resolution JALLIB PROCEDURE

Signature

procedure pwm1_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 1 for the 16-bit PWM1.
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm1

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1579_pwm1_16_bit_led.jal

-- -------------------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 1 of a PIC16F1579, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 1.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
--
include 16f1579                         -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    DISABLED         -- PLL off
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz
OSCCON_SPLLEN = FALSE                   -- software PLL off

enable_digital_io()                     -- make all pins digital I/O

include pps
pps_control_lock(FALSE)
RC0PPS = PPS_PWM1OUT                    -- pin_C0 is PWM1
pps_control_lock(TRUE)
pin_C0_direction = output

-- Configure PWM.
include pwm_hardware
-- 16-bit PWMs have their own PWM timer.
pwm1_max_resolution(1)                  -- Highest possible freq for PWM 1
pwm1_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm1_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm1_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm1_off()
   _usec_delay(500_000)
   pwm1_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm1.jal


pwm1_off - JALlib Procedures Help

pwm1_off JALLIB PROCEDURE

Signature

procedure pwm1_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm1

Parameters

None

Return Value

None

Example

From sample file: 16f1579_pwm1_16_bit_led.jal

-- -------------------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 1 of a PIC16F1579, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 1.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
--
include 16f1579                         -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    DISABLED         -- PLL off
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz
OSCCON_SPLLEN = FALSE                   -- software PLL off

enable_digital_io()                     -- make all pins digital I/O

include pps
pps_control_lock(FALSE)
RC0PPS = PPS_PWM1OUT                    -- pin_C0 is PWM1
pps_control_lock(TRUE)
pin_C0_direction = output

-- Configure PWM.
include pwm_hardware
-- 16-bit PWMs have their own PWM timer.
pwm1_max_resolution(1)                  -- Highest possible freq for PWM 1
pwm1_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm1_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm1_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm1_off()
   _usec_delay(500_000)
   pwm1_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm1.jal


pwm1_on - JALlib Procedures Help

pwm1_on JALLIB PROCEDURE

Signature

procedure pwm1_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM1_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm1

Parameters

None

Return Value

None

Example

From sample file: 16f648a_pwm_sound.jal

-- Title: Test program for hardware (built-in) PWM. Plays sound
-- Author: Sebastien Lelong, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample show how to use PWM with a constant duty cycle and
-- a variable frequency. It plays a "nice" melody (connect a small piezzo)
-- Frequencies from 0 to 100_000Hz are played. At the beginning, no sound will come
-- the buzzer, because frequency is too low (no valid combination of PR2/T2CON)
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_pwm_sound.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section ccp
-- backlight control (can be variable and digital on this pin)
alias lcd_bl is pin_b3
alias lcd_bl_direction is pin_b3_direction
enable_digital_io()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
-- Let's go !!!
pwm1_on()

var dword counter = 0
forever loop

   for 100_000 using counter loop
      pwm_set_frequency(counter)
      -- Setting @50% gives max volume
      -- must be re-computed each time the frequency
      -- changes, because it depends on PR2 value
      pwm1_set_dutycycle_percent(50)
   end loop

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm1.jal


pwm1_set_dutycycle_percent - JALlib Procedures Help

pwm1_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm1_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM1_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm1

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f648a_pwm_sound.jal

-- Title: Test program for hardware (built-in) PWM. Plays sound
-- Author: Sebastien Lelong, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample show how to use PWM with a constant duty cycle and
-- a variable frequency. It plays a "nice" melody (connect a small piezzo)
-- Frequencies from 0 to 100_000Hz are played. At the beginning, no sound will come
-- the buzzer, because frequency is too low (no valid combination of PR2/T2CON)
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_pwm_sound.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section ccp
-- backlight control (can be variable and digital on this pin)
alias lcd_bl is pin_b3
alias lcd_bl_direction is pin_b3_direction
enable_digital_io()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
-- Let's go !!!
pwm1_on()

var dword counter = 0
forever loop

   for 100_000 using counter loop
      pwm_set_frequency(counter)
      -- Setting @50% gives max volume
      -- must be re-computed each time the frequency
      -- changes, because it depends on PR2 value
      pwm1_set_dutycycle_percent(50)
   end loop

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm1.jal


pwm1_set_dutycycle_ratio - JALlib Procedures Help

pwm1_set_dutycycle_ratio JALLIB PROCEDURE

Signature

procedure pwm1_set_dutycycle_ratio(word in ratio) is

Description

Purpose: Set duty cycle in the range 0..1023 PWM steps.
Arguments: word - dutycycle ration in range 0..1023
Notes: - The duty cycle will be set to the specified ratio of the maximum
value for the current PWM frequency and Fosc.
- The resolution is about 1 pro mille
- The number of available PWM steps can be lower than 1023 with
high PWM frequencies or low Fosc values.
- pin_PWM1_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm1

Parameters

  • ratio - word in

Return Value

None

Example

From sample file: 18f4525_servo_rc_slave.jal

-- Title: RC Servo Slave sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows your PIC to read pulses given by a RC
--              receiver. Connect your PIC to a rc receiver the same way you
--              would connect a RC servo. This will use the rc_servo_slave
--              library to output a value to the serial port dependant on
--              where your fingers are moving the controls on your remote
--              transmitter. PIC will read the pulse width at the receiver.
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B. If you are using another
-- port, INTCON_RBIE & INTCON_RBIF may be named differently.
-- Check your datasheet for a interrupt-on-change pin.
--
-- Connect clock_out pin directly to int_on_change pin for an example without
-- an actual RC receiver.
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- choose pins to use for interrupt on change
const byte int_on_change_pins[] = {"B",4,"B",5} -- interrupt on change pin 0 and 1,  B4 and B5
include interrupt_on_change
int_on_change_init()

-- setup servo slave lib
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_0 = TRUE -- use interrupt on change pin 0
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_1 = TRUE -- use interrupt on change pin 1
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_2 = 0 -- use interrupt on change pin 2
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_3 = 0 -- use interrupt on change pin 3
--
const SERVO_SLAVE_USE_TIMER = 1     -- choose a timer
--
-- set your min/max values (0 to 100)
-- adjust SERVO_SLAVE_MIN first, then adjust SERVO_SLAVE_MAX
-- so output values will range from 0 to 255.
const SERVO_SLAVE_MIN = 0 -- default is 0
const SERVO_SLAVE_MAX = 0 -- default is 0
--
include servo_rc_slave
servo_slave_init()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on() -- turn on PWM1
pwm2_on() -- turn on PWM1

-- define clock out pin
alias clock_out           is pin_a1
alias clock_out_direction is pin_a1_direction
clock_out_direction = output

-- main loop
forever loop
   -- create a pulse to measure
   -- if your receiver is not connected, you may use this signal.
   clock_out = high
   _usec_delay(1500) -- 500 to 2_500 (0.5ms to 2.5ms)
   clock_out = low
   _usec_delay(20_000)

   -- SIGNAL 1
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[0] == TRUE then
      -- set the led brightness
      pwm1_set_dutycycle_ratio( servo_slave[0] << 2)
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[0])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm1_set_dutycycle_ratio(0) -- turn led off
   end if

   serial_data = " "
   serial_data = "-"
   serial_data = " "

   -- SIGNAL 2
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[1] == TRUE then
      -- set the led brightness
      pwm2_set_dutycycle_ratio( servo_slave[1] << 2 )
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[1])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm2_set_dutycycle_ratio(1) -- turn led off
   end if

   -- send crlf to serial port
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: pwm_pwm1.jal


pwm2_max_resolution - JALlib Procedures Help

pwm2_max_resolution JALLIB PROCEDURE

Signature

procedure pwm2_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 2 for the 16-bit PWM2.
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm2

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1579_pwm2_16_bit_led.jal

-- -------------------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 2 of a PIC16F1579, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel .
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
--
include 16f1579                         -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    DISABLED         -- PLL off
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz
OSCCON_SPLLEN = FALSE                   -- software PLL off

enable_digital_io()                     -- make all pins digital I/O

include pps
pps_control_lock(FALSE)
RC1PPS = PPS_PWM2OUT                    -- pin_C1 is PWM2
pps_control_lock(TRUE)
pin_C1_direction = output

-- Configure PWM.
include pwm_hardware
-- 16-bit PWMs have their own PWM timer.
pwm2_max_resolution(1)                  -- Highest possible freq for PWM 2
pwm2_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm2_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm2_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm2_off()
   _usec_delay(500_000)
   pwm2_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm2.jal


pwm2_off - JALlib Procedures Help

pwm2_off JALLIB PROCEDURE

Signature

procedure pwm2_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm2

Parameters

None

Return Value

None

Example

From sample file: 16f877a_pwm2.jal

-- ------------------------------------------------------
-- Title: Test program for pwm2.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: setup: a led on ccp2
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877a_startersguide.jal
--    * test : test_pwm2.jal
--

;@jallib section chipdef
-- chip setup
include 16f877a

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled

enable_digital_io()

-- Configure PWM
pin_ccp2_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm2_on()

forever loop
    var byte i
    i = 0
    -- loop up and down, to produce different duty cycle
    while i < 100 loop
        pwm2_set_dutycycle_percent(i)
        _usec_delay(10000)
        i = i + 1
    end loop
    while i > 0 loop
        pwm2_set_dutycycle_percent(i)
        _usec_delay(10000)
        i = i - 1
    end loop
    -- turning off, the LED lights at max.
    _usec_delay(500000)
    pwm2_off()
    _usec_delay(500000)
    pwm2_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm2.jal


pwm2_on - JALlib Procedures Help

pwm2_on JALLIB PROCEDURE

Signature

procedure pwm2_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM2_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm2

Parameters

None

Return Value

None

Example

From sample file: 18f4525_servo_rc_slave.jal

-- Title: RC Servo Slave sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows your PIC to read pulses given by a RC
--              receiver. Connect your PIC to a rc receiver the same way you
--              would connect a RC servo. This will use the rc_servo_slave
--              library to output a value to the serial port dependant on
--              where your fingers are moving the controls on your remote
--              transmitter. PIC will read the pulse width at the receiver.
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B. If you are using another
-- port, INTCON_RBIE & INTCON_RBIF may be named differently.
-- Check your datasheet for a interrupt-on-change pin.
--
-- Connect clock_out pin directly to int_on_change pin for an example without
-- an actual RC receiver.
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- choose pins to use for interrupt on change
const byte int_on_change_pins[] = {"B",4,"B",5} -- interrupt on change pin 0 and 1,  B4 and B5
include interrupt_on_change
int_on_change_init()

-- setup servo slave lib
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_0 = TRUE -- use interrupt on change pin 0
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_1 = TRUE -- use interrupt on change pin 1
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_2 = 0 -- use interrupt on change pin 2
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_3 = 0 -- use interrupt on change pin 3
--
const SERVO_SLAVE_USE_TIMER = 1     -- choose a timer
--
-- set your min/max values (0 to 100)
-- adjust SERVO_SLAVE_MIN first, then adjust SERVO_SLAVE_MAX
-- so output values will range from 0 to 255.
const SERVO_SLAVE_MIN = 0 -- default is 0
const SERVO_SLAVE_MAX = 0 -- default is 0
--
include servo_rc_slave
servo_slave_init()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on() -- turn on PWM1
pwm2_on() -- turn on PWM1

-- define clock out pin
alias clock_out           is pin_a1
alias clock_out_direction is pin_a1_direction
clock_out_direction = output

-- main loop
forever loop
   -- create a pulse to measure
   -- if your receiver is not connected, you may use this signal.
   clock_out = high
   _usec_delay(1500) -- 500 to 2_500 (0.5ms to 2.5ms)
   clock_out = low
   _usec_delay(20_000)

   -- SIGNAL 1
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[0] == TRUE then
      -- set the led brightness
      pwm1_set_dutycycle_ratio( servo_slave[0] << 2)
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[0])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm1_set_dutycycle_ratio(0) -- turn led off
   end if

   serial_data = " "
   serial_data = "-"
   serial_data = " "

   -- SIGNAL 2
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[1] == TRUE then
      -- set the led brightness
      pwm2_set_dutycycle_ratio( servo_slave[1] << 2 )
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[1])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm2_set_dutycycle_ratio(1) -- turn led off
   end if

   -- send crlf to serial port
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: pwm_pwm2.jal


pwm2_set_dutycycle_percent - JALlib Procedures Help

pwm2_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm2_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM2_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm2

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f877a_pwm2.jal

-- ------------------------------------------------------
-- Title: Test program for pwm2.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: setup: a led on ccp2
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877a_startersguide.jal
--    * test : test_pwm2.jal
--

;@jallib section chipdef
-- chip setup
include 16f877a

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled

enable_digital_io()

-- Configure PWM
pin_ccp2_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm2_on()

forever loop
    var byte i
    i = 0
    -- loop up and down, to produce different duty cycle
    while i < 100 loop
        pwm2_set_dutycycle_percent(i)
        _usec_delay(10000)
        i = i + 1
    end loop
    while i > 0 loop
        pwm2_set_dutycycle_percent(i)
        _usec_delay(10000)
        i = i - 1
    end loop
    -- turning off, the LED lights at max.
    _usec_delay(500000)
    pwm2_off()
    _usec_delay(500000)
    pwm2_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm2.jal


pwm2_set_dutycycle_ratio - JALlib Procedures Help

pwm2_set_dutycycle_ratio JALLIB PROCEDURE

Signature

procedure pwm2_set_dutycycle_ratio(word in ratio) is

Description

Purpose: Set duty cycle in the range 0..1023 PWM steps.
Arguments: word - dutycycle ration in range 0..1023
Notes: - The duty cycle will be set to the specified ratio of the maximum
value for the current PWM frequency and Fosc.
- The resolution is about 1 pro mille
- The number of available PWM steps can be lower than 1023 with
high PWM frequencies or low Fosc values.
- pin_PWM2_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm2

Parameters

  • ratio - word in

Return Value

None

Example

From sample file: 18f4525_servo_rc_slave.jal

-- Title: RC Servo Slave sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows your PIC to read pulses given by a RC
--              receiver. Connect your PIC to a rc receiver the same way you
--              would connect a RC servo. This will use the rc_servo_slave
--              library to output a value to the serial port dependant on
--              where your fingers are moving the controls on your remote
--              transmitter. PIC will read the pulse width at the receiver.
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B. If you are using another
-- port, INTCON_RBIE & INTCON_RBIF may be named differently.
-- Check your datasheet for a interrupt-on-change pin.
--
-- Connect clock_out pin directly to int_on_change pin for an example without
-- an actual RC receiver.
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- choose pins to use for interrupt on change
const byte int_on_change_pins[] = {"B",4,"B",5} -- interrupt on change pin 0 and 1,  B4 and B5
include interrupt_on_change
int_on_change_init()

-- setup servo slave lib
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_0 = TRUE -- use interrupt on change pin 0
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_1 = TRUE -- use interrupt on change pin 1
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_2 = 0 -- use interrupt on change pin 2
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_3 = 0 -- use interrupt on change pin 3
--
const SERVO_SLAVE_USE_TIMER = 1     -- choose a timer
--
-- set your min/max values (0 to 100)
-- adjust SERVO_SLAVE_MIN first, then adjust SERVO_SLAVE_MAX
-- so output values will range from 0 to 255.
const SERVO_SLAVE_MIN = 0 -- default is 0
const SERVO_SLAVE_MAX = 0 -- default is 0
--
include servo_rc_slave
servo_slave_init()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on() -- turn on PWM1
pwm2_on() -- turn on PWM1

-- define clock out pin
alias clock_out           is pin_a1
alias clock_out_direction is pin_a1_direction
clock_out_direction = output

-- main loop
forever loop
   -- create a pulse to measure
   -- if your receiver is not connected, you may use this signal.
   clock_out = high
   _usec_delay(1500) -- 500 to 2_500 (0.5ms to 2.5ms)
   clock_out = low
   _usec_delay(20_000)

   -- SIGNAL 1
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[0] == TRUE then
      -- set the led brightness
      pwm1_set_dutycycle_ratio( servo_slave[0] << 2)
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[0])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm1_set_dutycycle_ratio(0) -- turn led off
   end if

   serial_data = " "
   serial_data = "-"
   serial_data = " "

   -- SIGNAL 2
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[1] == TRUE then
      -- set the led brightness
      pwm2_set_dutycycle_ratio( servo_slave[1] << 2 )
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[1])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm2_set_dutycycle_ratio(1) -- turn led off
   end if

   -- send crlf to serial port
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: pwm_pwm2.jal


pwm3_max_resolution - JALlib Procedures Help

pwm3_max_resolution JALLIB PROCEDURE

Signature

procedure pwm3_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 3 for the 16-bit PWM3.
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm3

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1579_pwm3_16_bit_led.jal

-- -------------------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 3 of a PIC16F1579, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 3.
--              It progressively light up and down a LED connected to pin C2.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
--
include 16f1579                         -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    DISABLED         -- PLL off
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz
OSCCON_SPLLEN = FALSE                   -- software PLL off

enable_digital_io()                     -- make all pins digital I/O

include pps
pps_control_lock(FALSE)
RC2PPS = PPS_PWM3OUT                    -- pin_C2 is PWM3
pps_control_lock(TRUE)
pin_C2_direction = output

-- Configure PWM.
include pwm_hardware
-- 16-bit PWMs have their own PWM timer.
pwm3_max_resolution(1)                  -- Highest possible freq for PWM 3
pwm3_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm3_off()
   _usec_delay(500_000)
   pwm3_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm3.jal


pwm3_off - JALlib Procedures Help

pwm3_off JALLIB PROCEDURE

Signature

procedure pwm3_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_ccp3

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm3_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 3 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 3.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM3OUT                    -- pin_C0 is PWM3
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm3_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm3_off()
   _usec_delay(500_000)
   pwm3_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp3.jal


pwm3_on - JALlib Procedures Help

pwm3_on JALLIB PROCEDURE

Signature

procedure pwm3_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM3_direction should be set to output

Include

To use this procedure, include the library:

include pwm_ccp3

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm3_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 3 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 3.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM3OUT                    -- pin_C0 is PWM3
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm3_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm3_off()
   _usec_delay(500_000)
   pwm3_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp3.jal


pwm3_set_dutycycle_percent - JALlib Procedures Help

pwm3_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm3_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_CCP3_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_ccp3

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1778_pwm3_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 3 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 3.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM3OUT                    -- pin_C0 is PWM3
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm3_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm3_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm3_off()
   _usec_delay(500_000)
   pwm3_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp3.jal


pwm4_max_resolution - JALlib Procedures Help

pwm4_max_resolution JALLIB PROCEDURE

Signature

procedure pwm4_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 4 for the 16-bit PWM4.
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm4

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1579_pwm4_16_bit_led.jal

-- -------------------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 4 of a PIC16F1579, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 4.
--              It progressively light up and down a LED connected to pin C3.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
--
include 16f1579                         -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000        -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    DISABLED         -- PLL off
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1101                    -- 4 MHz
OSCCON_SPLLEN = FALSE                   -- software PLL off

enable_digital_io()                     -- make all pins digital I/O

include pps
pps_control_lock(FALSE)
RC3PPS = PPS_PWM4OUT                    -- pin_C3 is PWM4
pps_control_lock(TRUE)
pin_C3_direction = output

-- Configure PWM.
include pwm_hardware
-- 16-bit PWMs have their own PWM timer.
pwm4_max_resolution(1)                  -- Highest possible freq for PWM 4
pwm4_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm4_off()
   _usec_delay(500_000)
   pwm4_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm4.jal


pwm4_off - JALlib Procedures Help

pwm4_off JALLIB PROCEDURE

Signature

procedure pwm4_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_ccp4

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm4_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 4 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 4.
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                        -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC1PPS = PPS_PWM4OUT                    -- pin_C1 is PWM44
pps_control_lock(TRUE)                  -- lock PPS module
pin_C1_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm4_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm4_off()
   _usec_delay(500_000)
   pwm4_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp4.jal


pwm4_on - JALlib Procedures Help

pwm4_on JALLIB PROCEDURE

Signature

procedure pwm4_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM4_direction should be set to output

Include

To use this procedure, include the library:

include pwm_ccp4

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm4_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 4 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 4.
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                        -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC1PPS = PPS_PWM4OUT                    -- pin_C1 is PWM44
pps_control_lock(TRUE)                  -- lock PPS module
pin_C1_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm4_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm4_off()
   _usec_delay(500_000)
   pwm4_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp4.jal


pwm4_set_dutycycle_percent - JALlib Procedures Help

pwm4_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm4_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_CCP4_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_ccp4

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1778_pwm4_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 4 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 4.
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                        -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC1PPS = PPS_PWM4OUT                    -- pin_C1 is PWM44
pps_control_lock(TRUE)                  -- lock PPS module
pin_C1_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm4_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm4_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm4_off()
   _usec_delay(500_000)
   pwm4_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp4.jal


pwm5_max_resolution - JALlib Procedures Help

pwm5_max_resolution JALLIB PROCEDURE

Signature

procedure pwm5_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 5 for the 16-bit PWM5.
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm5

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1778_pwm5_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 5 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 5.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM5OUT                    -- pin_C0 is PWM5
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm5_max_resolution(1)                  -- max res. with highest possible freq.
pwm5_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm5_off()
   _usec_delay(500_000)
   pwm5_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm5.jal


pwm5_off - JALlib Procedures Help

pwm5_off JALLIB PROCEDURE

Signature

procedure pwm5_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_ccp5

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm5_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 5 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 5.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM5OUT                    -- pin_C0 is PWM5
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm5_max_resolution(1)                  -- max res. with highest possible freq.
pwm5_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm5_off()
   _usec_delay(500_000)
   pwm5_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp5.jal


pwm5_on - JALlib Procedures Help

pwm5_on JALLIB PROCEDURE

Signature

procedure pwm5_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM5_direction should be set to output

Include

To use this procedure, include the library:

include pwm_ccp5

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm5_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 5 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 5.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM5OUT                    -- pin_C0 is PWM5
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm5_max_resolution(1)                  -- max res. with highest possible freq.
pwm5_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm5_off()
   _usec_delay(500_000)
   pwm5_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp5.jal


pwm5_set_dutycycle_percent - JALlib Procedures Help

pwm5_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm5_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_CCP5_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_ccp5

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1778_pwm5_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 5 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 5.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM5OUT                    -- pin_C0 is PWM5
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm5_max_resolution(1)                  -- max res. with highest possible freq.
pwm5_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm5_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm5_off()
   _usec_delay(500_000)
   pwm5_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp5.jal


pwm6_max_resolution - JALlib Procedures Help

pwm6_max_resolution JALLIB PROCEDURE

Signature

procedure pwm6_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 6 for the 16-bit PWM (if present).
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm6

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1778_pwm6_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 6 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 6.
--              It progressively light up and down a LED connected to port C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC1PPS = PPS_PWM6OUT                    -- pin_C1 is PWM6
pps_control_lock(TRUE)                  -- lock PPS module
pin_C1_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm6_max_resolution(1)                  -- max res. with highest possible freq.
pwm6_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm6_off()
   _usec_delay(500_000)
   pwm6_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm6.jal


pwm6_off - JALlib Procedures Help

pwm6_off JALLIB PROCEDURE

Signature

procedure pwm6_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm6

Parameters

None

Return Value

None

Example

From sample file: 18f26k42_pwm6_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 6 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 6.
--              It progressively light up and down a LED connected to pin C3.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC3PPS = PPS_PWM6                      -- pin_C3 is PWM6
pps_control_lock(TRUE)                 -- lock PPS module
pin_C3_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm6_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm6_off()
   _usec_delay(500_000)
   pwm6_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm6.jal


pwm6_on - JALlib Procedures Help

pwm6_on JALLIB PROCEDURE

Signature

procedure pwm6_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM6_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm6

Parameters

None

Return Value

None

Example

From sample file: 18f26k42_pwm6_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 6 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 6.
--              It progressively light up and down a LED connected to pin C3.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC3PPS = PPS_PWM6                      -- pin_C3 is PWM6
pps_control_lock(TRUE)                 -- lock PPS module
pin_C3_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm6_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm6_off()
   _usec_delay(500_000)
   pwm6_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm6.jal


pwm6_set_dutycycle_percent - JALlib Procedures Help

pwm6_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm6_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM6_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm6

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 18f26k42_pwm6_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 6 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 6.
--              It progressively light up and down a LED connected to pin C3.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000       -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC3PPS = PPS_PWM6                      -- pin_C3 is PWM6
pps_control_lock(TRUE)                 -- lock PPS module
pin_C3_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm6_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm6_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm6_off()
   _usec_delay(500_000)
   pwm6_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm6.jal


pwm7_off - JALlib Procedures Help

pwm7_off JALLIB PROCEDURE

Signature

procedure pwm7_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm7

Parameters

None

Return Value

None

Example

From sample file: 18f26k42_pwm7_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 7 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 7.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000            -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC0PPS = PPS_PWM7                      -- pin_C0 is PWM7
pps_control_lock(TRUE)                 -- lock PPS module
pin_C0_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm7_on()

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm7_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm7_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm7_off()
   _usec_delay(500_000)
   pwm7_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm7.jal


pwm7_on - JALlib Procedures Help

pwm7_on JALLIB PROCEDURE

Signature

procedure pwm7_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM7_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm7

Parameters

None

Return Value

None

Example

From sample file: 18f26k42_pwm7_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 7 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 7.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000            -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC0PPS = PPS_PWM7                      -- pin_C0 is PWM7
pps_control_lock(TRUE)                 -- lock PPS module
pin_C0_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm7_on()

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm7_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm7_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm7_off()
   _usec_delay(500_000)
   pwm7_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm7.jal


pwm7_set_dutycycle_percent - JALlib Procedures Help

pwm7_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm7_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM7_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm7

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 18f26k42_pwm7_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 7 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 7.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000            -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC0PPS = PPS_PWM7                      -- pin_C0 is PWM7
pps_control_lock(TRUE)                 -- lock PPS module
pin_C0_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm7_on()

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm7_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm7_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm7_off()
   _usec_delay(500_000)
   pwm7_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm7.jal


pwm8_off - JALlib Procedures Help

pwm8_off JALLIB PROCEDURE

Signature

procedure pwm8_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_ccp8

Parameters

None

Return Value

None

Example

From sample file: 18f26k42_pwm8_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 8 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 8.
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000            -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC1PPS = PPS_PWM8                      -- pin_C1 is PWM8
pps_control_lock(TRUE)                 -- lock PPS module
pin_C1_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm8_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm8_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm8_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm8_off()
   _usec_delay(500_000)
   pwm8_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp8.jal


pwm8_on - JALlib Procedures Help

pwm8_on JALLIB PROCEDURE

Signature

procedure pwm8_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM8_direction should be set to output

Include

To use this procedure, include the library:

include pwm_ccp8

Parameters

None

Return Value

None

Example

From sample file: 18f26k42_pwm8_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 8 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 8.
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000            -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC1PPS = PPS_PWM8                      -- pin_C1 is PWM8
pps_control_lock(TRUE)                 -- lock PPS module
pin_C1_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm8_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm8_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm8_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm8_off()
   _usec_delay(500_000)
   pwm8_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp8.jal


pwm8_set_dutycycle_percent - JALlib Procedures Help

pwm8_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm8_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_CCP8_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_ccp8

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 18f26k42_pwm8_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 8 of PIC18F26K42, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 8.
--              It progressively light up and down a LED connected to pin C1.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 18f26k42                       -- target PICmicro
--
-- This program uses the internal oscillator at 4 MHz.
pragma target clock    4_000_000            -- oscillator frequency
--
pragma target OSC      OFF             -- internal oscillator
pragma target RSTOSC   HFINTOSC_64MHZ  -- select 64 MHz
pragma target CLKOUTEN DISABLED        -- no clock output
pragma target WDT      DISABLED        -- watchdog
pragma target XINST    DISABLED        -- do not use extended instructionset
pragma target DEBUG    DISABLED        -- no debugging
pragma target BROWNOUT DISABLED        -- no brownout reset
pragma target FCMEN    DISABLED        -- no clock monitoring
pragma target CSWEN    ENABLED         -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED         -- low voltage programming
pragma target MCLR     EXTERNAL        -- external reset
pragma target MVECEN   DISABLED        -- Do not use multi vectored interrupts
OSCFRQ_HFFRQ = 0b0010                  -- Fosc 64 -> 4 MHz

enable_digital_io()                    -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                -- unlock PPS module
RC1PPS = PPS_PWM8                      -- pin_C1 is PWM8
pps_control_lock(TRUE)                 -- lock PPS module
pin_C1_direction = output              -- don't forget to set this to output

include pwm_hardware                   -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                  -- max res. with highest possible freq.
pwm8_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm8_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm8_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm8_off()
   _usec_delay(500_000)
   pwm8_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp8.jal


pwm9_off - JALlib Procedures Help

pwm9_off JALLIB PROCEDURE

Signature

procedure pwm9_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm9

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm9_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 9 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 9.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM9OUT                    -- pin_C0 is PWM9
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm9_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm9_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm9_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm9_off()
   _usec_delay(500_000)
   pwm9_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm9.jal


pwm9_on - JALlib Procedures Help

pwm9_on JALLIB PROCEDURE

Signature

procedure pwm9_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM9_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm9

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm9_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 9 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 9.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM9OUT                    -- pin_C0 is PWM9
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm9_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm9_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm9_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm9_off()
   _usec_delay(500_000)
   pwm9_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm9.jal


pwm9_set_dutycycle_percent - JALlib Procedures Help

pwm9_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm9_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM9_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm9

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1778_pwm9_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 9 of a PIC16F1778, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 9.
--              It progressively light up and down a LED connected to pin C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM9OUT                    -- pin_C0 is PWM9
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm9_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm9_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm9_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm9_off()
   _usec_delay(500_000)
   pwm9_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm9.jal


pwm10_off - JALlib Procedures Help

pwm10_off JALLIB PROCEDURE

Signature

procedure pwm10_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_ccp10

Parameters

None

Return Value

None

Example

From sample file: 16f1777_pwm10_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 10 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 10.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1777                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM10OUT                   -- pin_C0 is PWM10
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm10_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm10_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm10_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm10_off()
   _usec_delay(500_000)
   pwm10_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp10.jal


pwm10_on - JALlib Procedures Help

pwm10_on JALLIB PROCEDURE

Signature

procedure pwm10_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM10_direction should be set to output

Include

To use this procedure, include the library:

include pwm_ccp10

Parameters

None

Return Value

None

Example

From sample file: 16f1777_pwm10_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 10 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 10.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1777                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM10OUT                   -- pin_C0 is PWM10
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm10_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm10_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm10_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm10_off()
   _usec_delay(500_000)
   pwm10_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp10.jal


pwm10_set_dutycycle_percent - JALlib Procedures Help

pwm10_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm10_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_CCP10_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_ccp10

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1777_pwm10_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 10-bit PWM channel 10 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 10-bit PWM channel 10.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1777                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM10OUT                   -- pin_C0 is PWM10
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 10-bit PWMs use Timer2 so use the common pwm_max_resolution.
pwm_max_resolution(1)                   -- max res. with highest possible freq.
pwm10_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm10_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm10_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm10_off()
   _usec_delay(500_000)
   pwm10_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_ccp10.jal


pwm11_max_resolution - JALlib Procedures Help

pwm11_max_resolution JALLIB PROCEDURE

Signature

procedure pwm11_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 11 for the 16-bit PWM (if present).
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm11

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1778_pwm11_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 11 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 11.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM11OUT                   -- pin_C0 is PWM11
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm11_max_resolution(1)                 -- max res. with highest possible freq.
pwm11_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm11_off()
   _usec_delay(500_000)
   pwm11_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm11.jal


pwm11_off - JALlib Procedures Help

pwm11_off JALLIB PROCEDURE

Signature

procedure pwm11_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm11

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm11_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 11 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 11.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM11OUT                   -- pin_C0 is PWM11
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm11_max_resolution(1)                 -- max res. with highest possible freq.
pwm11_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm11_off()
   _usec_delay(500_000)
   pwm11_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm11.jal


pwm11_on - JALlib Procedures Help

pwm11_on JALLIB PROCEDURE

Signature

procedure pwm11_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM11_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm11

Parameters

None

Return Value

None

Example

From sample file: 16f1778_pwm11_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 11 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 11.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM11OUT                   -- pin_C0 is PWM11
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm11_max_resolution(1)                 -- max res. with highest possible freq.
pwm11_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm11_off()
   _usec_delay(500_000)
   pwm11_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm11.jal


pwm11_set_dutycycle_percent - JALlib Procedures Help

pwm11_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm11_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM11_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm11

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1778_pwm11_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 11 of PIC16F1777, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 11.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1778                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM11OUT                   -- pin_C0 is PWM11
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm11_max_resolution(1)                 -- max res. with highest possible freq.
pwm11_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm11_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm11_off()
   _usec_delay(500_000)
   pwm11_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm11.jal


pwm12_max_resolution - JALlib Procedures Help

pwm12_max_resolution JALLIB PROCEDURE

Signature

procedure pwm12_max_resolution(byte in prescaler) is

Description

Set the prescaler value for Timer 12 for the 16-bit PWM (if present).
The timer will be running.

Include

To use this procedure, include the library:

include pwm_pwm12

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 16f1779_pwm12_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 12 of PIC16F1779, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 12.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1779                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM12OUT                   -- pin_C0 is PWM12
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm12_max_resolution(1)                 -- max res. with highest possible freq.
pwm12_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm12_off()
   _usec_delay(500_000)
   pwm12_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm12.jal


pwm12_off - JALlib Procedures Help

pwm12_off JALLIB PROCEDURE

Signature

procedure pwm12_off() is

Description

Purpose: PWM mode off
Arguments: none

Include

To use this procedure, include the library:

include pwm_pwm12

Parameters

None

Return Value

None

Example

From sample file: 16f1779_pwm12_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 12 of PIC16F1779, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 12.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1779                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM12OUT                   -- pin_C0 is PWM12
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm12_max_resolution(1)                 -- max res. with highest possible freq.
pwm12_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm12_off()
   _usec_delay(500_000)
   pwm12_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm12.jal


pwm12_on - JALlib Procedures Help

pwm12_on JALLIB PROCEDURE

Signature

procedure pwm12_on() is

Description

Purpose: Set PWM on
Arguments: none
Notes: - duty cycle is restored from shadow registers
- pin_PWM12_direction should be set to output

Include

To use this procedure, include the library:

include pwm_pwm12

Parameters

None

Return Value

None

Example

From sample file: 16f1779_pwm12_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 12 of PIC16F1779, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 12.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1779                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM12OUT                   -- pin_C0 is PWM12
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm12_max_resolution(1)                 -- max res. with highest possible freq.
pwm12_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm12_off()
   _usec_delay(500_000)
   pwm12_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm12.jal


pwm12_set_dutycycle_percent - JALlib Procedures Help

pwm12_set_dutycycle_percent JALLIB PROCEDURE

Signature

procedure pwm12_set_dutycycle_percent(byte in percent) is

Description

Purpose: Set duty cycle as a percentage, allowing max 100 PWM steps.
The duty cycle will be set to the specified percentage of the maximum
for the current PWM frequency and Fosc.
Arguments: byte - dutycycle as a percentage (allowed range: 0..100)
Notes: - The number of available PWM steps can be lower than 100 with
(very) high PWM frequencies and low Fosc.
- The steps may not all be equal. The lower the actual resolution
the bigger the differences between steps may be.
- pin_PWM12_direction should be set to output!

Include

To use this procedure, include the library:

include pwm_pwm12

Parameters

  • percent - byte in

Return Value

None

Example

From sample file: 16f1779_pwm12_16_bit_led.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program using 16-bit PWM channel 12 of PIC16F1779, using a LED.
-- Author: Rob Jansen, Copyright (c) 2024..2024, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This sample show how to use the 16-bit PWM channel 12.
--              It progressively light up and down a LED connected to port C0.
--
-- Notes: This file is a partial copy of pwm_led.jal created by Sebastien Lelong and
--        adapted manually.
--
include 16f1779                         -- target PICmicro
--
-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000       -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT  -- internal oscillator
pragma target PLLEN    ENABLED          -- PLL on (4 x)
pragma target CLKOUTEN DISABLED         -- no clock output
pragma target WDT      DISABLED         -- watchdog
pragma target BROWNOUT DISABLED         -- no brownout reset
pragma target FCMEN    DISABLED         -- no clock monitoring
pragma target IESO     DISABLED         -- no int/ext osc switching
pragma target LVP      ENABLED          -- low voltage programming
pragma target MCLR     EXTERNAL         -- external reset
OSCCON_SCS = 0                          -- select primary oscillator
OSCCON_IRCF = 0b1110                    -- 8 MHz with PLL gives 32 MHz
OSCCON_SPLLEN = TRUE                    -- PLL always enabled.
--
enable_digital_io()                     -- set all IO as digital

-- PWM setup.
include pps
pps_control_lock(FALSE)                 -- unlock PPS module
RC0PPS = PPS_PWM12OUT                   -- pin_C0 is PWM12
pps_control_lock(TRUE)                  -- lock PPS module
pin_C0_direction = output               -- don't forget to set this to output

include pwm_hardware                    -- fetch PWM library
-- 16-bit PWMs have their own PWM timer.
pwm12_max_resolution(1)                 -- max res. with highest possible freq.
pwm12_on

var byte i

forever loop

   i = 0
   -- loop up and down, to produce different duty cycle
   while i < 100 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i + 1
   end loop

   while i > 0 loop
      pwm12_set_dutycycle_percent(i)
      _usec_delay(10000)
      i = i - 1
   end loop

   -- turning off, the LED
   _usec_delay(500_000)
   pwm12_off()
   _usec_delay(500_000)
   pwm12_on()

end loop

Generated by JALlib CHM Help System | Source: pwm_pwm12.jal


pwm_backlight_init - JALlib Procedures Help

pwm_backlight_init JALLIB PROCEDURE

Signature

procedure pwm_backlight_init() is

Description

next procedure is unindented to have the definition included into the documentation
pwm_backlight_init - init backlight functions

Include

To use this procedure, include the library:

include lcd_backlight

Parameters

None

Return Value

None

Example

From sample file: 16f877_backlight.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for lcd_backlight test (basic test)
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
-- setup:   A hd44780 compatible display, used in 4-bit mode with backlight
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f877_dwarf.jal
--    * test : test_backlight.jal
--

;@jallib section chipdef
-- chip setup
include 16f877

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled
;@jallib section lcd_hd44780_4
-- LCD IO definition
alias lcd_rs           is pin_b5              -- LCD command/data select.
alias lcd_rs_direction is pin_b5_direction
alias lcd_en           is pin_b4              -- LCD data trigger
alias lcd_en_direction is pin_b4_direction

-- primary dataport nibble:
alias lcd_dataport is portb_low              -- LCD data  port
alias lcd_dataport_direction is portb_low_direction

-- alternative dataport bits:
alias lcd_d4 is pin_b0
alias lcd_d5 is pin_b1
alias lcd_d6 is pin_b2
alias lcd_d7 is pin_b3
alias lcd_d4_direction is pin_b0_direction
alias lcd_d5_direction is pin_b1_direction
alias lcd_d6_direction is pin_b2_direction
alias lcd_d7_direction is pin_b3_direction

const byte LCD_ROWS     = 2                     -- 2 lines
const byte LCD_CHARS    = 16                    -- 16 chars per line

;@jallib section led
-- LED IO definition
alias led             is pin_b6
alias led_direction   is pin_b6_direction
alias led2            is pin_a1
alias led2_direction  is pin_a1_direction
;@jallib section ccp
-- backlight control (can be variable and digital on this pin)
alias lcd_bl is pin_c2
alias lcd_bl_direction is pin_c2_direction

enable_digital_io() -- disable analog I/O (if any)

-- setup libs, io etc
lcd_rs_direction        = output
lcd_en_direction        = output
lcd_dataport_direction  = output

include print
include lcd_hd44780_4
include delay
lcd_init()                              -- initialize LCD

lcd_clear_screen()
lcd_home()

const byte teststring[] = "Backlight test."
print_string(lcd, teststring)

const byte lcd_backlight_pwm = 1 -- by selecting the pwm pin, lcd_backlight_variable() is enabled.
lcd_bl_direction = output
;const bit lcd_bl_inverted = true   -- define this when pin low turns backlight on

-- include & init backlight lib
include lcd_backlight
pwm_backlight_init()

var byte i
forever loop

   -- set backlight off for two seconds
   lcd_backlight(off)
   delay_100ms(20)

   -- set backlight on for two seconds
   lcd_backlight(on)
   delay_100ms(20)

   if(defined(lcd_backlight_pwm) == true) then

      -- we have variable backlight!

      -- first increase intensity
      for 255 using i loop
         lcd_backlight_variable(i)
         delay_1ms(10)
      end loop

      -- and decrease intensity
      for 255 using i loop
         lcd_backlight_variable(255-i)
         delay_1ms(10)
      end loop

   end if

end loop

Generated by JALlib CHM Help System | Source: lcd_backlight.jal


pwm_ccp1.jal - JALLIB Library Documentation

pwm_ccp1.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM1

Author

Stef Mientki, Copyright (C) 2002..2019, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM1 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM1 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm1_set_dutycycle_highres - Procedure
  • pwm1_off - Procedure
  • pwm1_on - Procedure
  • pwm1_set_dutycycle - Procedure
  • pwm1_set_dutycycle_highres - Procedure
  • pwm1_set_dutycycle_lowres - Procedure
  • pwm1_set_dutycycle_percent - Procedure
  • pwm1_set_dutycycle_ratio - Procedure
  • pwm1_set_percent_dutycycle - Procedure


pwm_ccp2.jal - JALLIB Library Documentation

pwm_ccp2.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM2

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM2 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM2 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm2_set_dutycycle_highres - Procedure
  • pwm2_off - Procedure
  • pwm2_on - Procedure
  • pwm2_set_dutycycle - Procedure
  • pwm2_set_dutycycle_highres - Procedure
  • pwm2_set_dutycycle_lowres - Procedure
  • pwm2_set_dutycycle_percent - Procedure
  • pwm2_set_dutycycle_ratio - Procedure
  • pwm2_set_percent_dutycycle - Procedure


pwm_ccp3.jal - JALLIB Library Documentation

pwm_ccp3.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM3

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM3 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM3 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm3_set_dutycycle_highres - Procedure
  • pwm3_off - Procedure
  • pwm3_on - Procedure
  • pwm3_set_dutycycle - Procedure
  • pwm3_set_dutycycle_highres - Procedure
  • pwm3_set_dutycycle_lowres - Procedure
  • pwm3_set_dutycycle_percent - Procedure
  • pwm3_set_dutycycle_ratio - Procedure
  • pwm3_set_percent_dutycycle - Procedure


pwm_ccp4.jal - JALLIB Library Documentation

pwm_ccp4.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM4

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM4 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM4 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm4_set_dutycycle_highres - Procedure
  • pwm4_off - Procedure
  • pwm4_on - Procedure
  • pwm4_set_dutycycle - Procedure
  • pwm4_set_dutycycle_highres - Procedure
  • pwm4_set_dutycycle_lowres - Procedure
  • pwm4_set_dutycycle_percent - Procedure
  • pwm4_set_dutycycle_ratio - Procedure
  • pwm4_set_percent_dutycycle - Procedure


pwm_ccp5.jal - JALLIB Library Documentation

pwm_ccp5.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM5

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM5 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM5 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm5_set_dutycycle_highres - Procedure
  • pwm5_off - Procedure
  • pwm5_on - Procedure
  • pwm5_set_dutycycle - Procedure
  • pwm5_set_dutycycle_highres - Procedure
  • pwm5_set_dutycycle_lowres - Procedure
  • pwm5_set_dutycycle_percent - Procedure
  • pwm5_set_dutycycle_ratio - Procedure
  • pwm5_set_percent_dutycycle - Procedure


pwm_ccp6.jal - JALLIB Library Documentation

pwm_ccp6.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM6

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM6 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM6 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm6_set_dutycycle_highres - Procedure
  • pwm6_off - Procedure
  • pwm6_on - Procedure
  • pwm6_set_dutycycle - Procedure
  • pwm6_set_dutycycle_highres - Procedure
  • pwm6_set_dutycycle_lowres - Procedure
  • pwm6_set_dutycycle_percent - Procedure
  • pwm6_set_dutycycle_ratio - Procedure
  • pwm6_set_percent_dutycycle - Procedure


pwm_ccp7.jal - JALLIB Library Documentation

pwm_ccp7.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM7

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM7 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM7 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm7_set_dutycycle_highres - Procedure
  • pwm7_off - Procedure
  • pwm7_on - Procedure
  • pwm7_set_dutycycle - Procedure
  • pwm7_set_dutycycle_highres - Procedure
  • pwm7_set_dutycycle_lowres - Procedure
  • pwm7_set_dutycycle_percent - Procedure
  • pwm7_set_dutycycle_ratio - Procedure
  • pwm7_set_percent_dutycycle - Procedure


pwm_ccp8.jal - JALLIB Library Documentation

pwm_ccp8.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM8

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM8 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM8 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm8_set_dutycycle_highres - Procedure
  • pwm8_off - Procedure
  • pwm8_on - Procedure
  • pwm8_set_dutycycle - Procedure
  • pwm8_set_dutycycle_highres - Procedure
  • pwm8_set_dutycycle_lowres - Procedure
  • pwm8_set_dutycycle_percent - Procedure
  • pwm8_set_dutycycle_ratio - Procedure
  • pwm8_set_percent_dutycycle - Procedure


pwm_ccp9.jal - JALLIB Library Documentation

pwm_ccp9.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM9

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM9 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM9 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm9_set_dutycycle_highres - Procedure
  • pwm9_off - Procedure
  • pwm9_on - Procedure
  • pwm9_set_dutycycle - Procedure
  • pwm9_set_dutycycle_highres - Procedure
  • pwm9_set_dutycycle_lowres - Procedure
  • pwm9_set_dutycycle_percent - Procedure
  • pwm9_set_dutycycle_ratio - Procedure
  • pwm9_set_percent_dutycycle - Procedure


pwm_ccp10.jal - JALLIB Library Documentation

pwm_ccp10.jal JALLIB LIBRARY

Title

hardware PWM control, dedicated to module PWM10

Author

Stef Mientki, Copyright (C) 2002-2006, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling.

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM10 module (of enhanced midrange)
This file is automatically included by pwm_hardware.jal
when the target PIC has a PWM10 module.

Notes

1. This is a heavy refactoring of the original pwm_hardware.jal
(Stef's lib)
2. Partly rewritten for JalV2 version 2.4l and Jallib revision 1171.
Reduced memory occupation. Added procedure for lowres PWM.
3. Changes dd October 2012 by Rob Hamerling
- added public procedure to set dutycycle with highest resolution (1023 steps).
- Make the pwm_set_dutycycle (highres, lowres and unqualified) private
(preceeded with an underscore). These procedures will be kept. but
with a 'deprecated' warning recommending to use the procedures for
relative settings.
-------------------------------------------------------------------------------------

Routines

  • _pwm10_set_dutycycle_highres - Procedure
  • pwm10_off - Procedure
  • pwm10_on - Procedure
  • pwm10_set_dutycycle - Procedure
  • pwm10_set_dutycycle_highres - Procedure
  • pwm10_set_dutycycle_lowres - Procedure
  • pwm10_set_dutycycle_percent - Procedure
  • pwm10_set_dutycycle_ratio - Procedure
  • pwm10_set_percent_dutycycle - Procedure


pwm_common.jal - JALLIB Library Documentation

pwm_common.jal JALLIB LIBRARY

Title

Hardware PWM control, common procedures

Author

Stef Mientki, Copyright (C) 2002..2024, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This lib handles common operations on PWM, regardless the channel number.
It is used in combination with one or more pwm_ccp<number> libraries
(eg. pwm_ccp1.jal, pwm_ccp2.jal, etc.). These libraries are included
automatically dependent of the configuration of the target PIC.
Supports 10-bit PWM and 16-bit PWM for PWM1..PWM12. At the moment of creation of
this library there were no PICs with 16-bit PWM for PWM7, PWM8, PWM9 and PWM10.
Oscillator refequency, PWM frequency and PWM resolution are a tighly coupled
set of parameters. Refer to the PWM section in the datasheets how these are related.

Notes

This is a heavy refactoring of the original pwm_hardware.jal (Stef's lib).
For 10-bit PWM Timer2 is always used, also when different timers can be assigned.
----------------------------------------------------------------------------

Global variable for all 10-bit PWM using Timer2.
10-bit PWM for all modules.
Shadow of PR2 (value incremented by 1, i.e. value in range 1..256)
Set to maximum value by default for maximum resolution.

Constants and Variables

pr_provisional - var dword = target_clock / freq -- 16-bit PWM use Fosc.
16-bit PWM use Fosc.

Routines

  • _pwm_determine_timer_and_prescale - Procedure
  • _pwm_get_prescaler_value - Procedure
  • pwm_get_resolution - Function returns word
  • pwm_max_resolution - Procedure
  • pwm_set_frequency - Procedure


pwm_hardware.jal - JALLIB Library Documentation

pwm_hardware.jal JALLIB LIBRARY

Title

Hardware PWM control

Author

Sebastien Lelong, Copyright (C) 2008..2024, all rights reserved., Adapted-by: Albert Faber, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Include this library if you want to use the PWM feature of the CCP module(s).
This library uses conditional compile to selectively include underlying PWM
libraries and number of PWM channels, according to the target PIC configuration.
Ex: - 16f88 has 1 PWM channel: including pwm_hardware will prepare PWM
for 1 channel (using pwm_ccp1.jal)
- 16f877 has 2 PWM channels: including pwm_hardware will prepare PWM
for 2 channels (using pwm_ccp1.jal and pwm_ccp2.jal)
- etc. for PICs with more CCP or PWM modules
Note: pin_CCPx_directions or pin_PWMx_directions must be set to output
by the application.
.
With using the PWM hardware a design choice must be made between desired
PWM frequency and desired PWM resolution (number of possible PWM steps).
Choosing maximum PWM resolution implies a relative low PWM frequency and
vice versa: a high frequency limits the number of available PWM steps.
The figures are dependent on the target clock speed.
Refer to pwm_common, pwm_ccp1, pwm_ccp2 ... etc. documentation to
understand how to use these PWM libraries.

Notes

1. Because the PWM libraries use conditional compilation and the 'alias'
keyword, at least JalV2 compiler version 2.4l is required.
2. These libraries use the pin alias names as declared in Jallib device
files since revision 1171, so Jallib release 0.4 is a minimum requirement.
3. Some PICs have extended CCP modules. These will be handled by these
PWM libraries as 'classic' CCP modules.
4. Some of the newer PICs have PWM module(s) but no CCP module(s) and
the naming convention of registers and pins differs from the older
PICs. These PICS are supported as well, with same procedure names as
PICs with CCP modules.
5. RJ: 10-bit and 16-bit PWM1-PWM12 are supported from 2024 onwards.

------ Alias ECCPxCON registers --------

Include common variables and procedures


pwm_max_resolution - JALlib Procedures Help

pwm_max_resolution JALLIB PROCEDURE

Signature

procedure pwm_max_resolution(byte in prescaler) is

Description

Purpose: Set all(!) CCP modules for max (10-bits) PWM resolution.
Arguments: byte - prescaler value for Timer2
Notes: - Allowed values of input parameter:
For PICs with 2 prescaler bits: 1, 4, 16 or 64
For PICs with 3 prescaler bits: 1, 2, 4, 8, 16, 32, 64 or 128
In case of an incorrect argument the highest prescaler value
will be used. Timer 2 will be running.
.
While setting maximum resolution, the Timer2 prescaler can be used to adjust
frequency to some extent with the Timer2 parameter.
Below a table showing the PWM frequencies for common clock speeds and different
Timer2 prescaler values for PIC with 2 prescaler bits (1..64) using Fosc/4.
Note that 10-bit PWM use Fosc/4 and 16-bit PWM use Fosc. Some 10-bit PWM and all
16-bit PWM have 3 prescaler bits (1..128), see the datasheet of your PIC.
||*Prescale*|| *4MHz* || *8MHz* || *10MHz* || *20MHz* || *32MHz* || *48MHz* ||
|| 1 || 3.90 kHz || 7.81 kHz || 9.77 kHz || 19.53 kHz || 31.25 kHz || 46.88 kHz ||
|| 4 || 976 Hz || 1.95 kHz || 2.44 kHz || 4.88 kHz || 7.81 kHz || 11.72 kHz ||
|| 16 || 244 Hz || 488 Hz || 610 Hz || 1.22 kHz || 1.95 kHz || 2.93 kHz ||
|| 64 || 61 Hz || 122 Hz || 152 Hz || 305 Hz || 488 Hz || 732 Hz ||
For 10-bit PWM PICs with more than one CCP module you should realize that all CCP
modules use Timer2 and PR2 for PWM operations. This means that the PWM
period (frequency) of all PWM output pins is the same.
Only the duty cycle can vary between one and another PWM pin.
PICs with 16-bits PWM have indepent PWM timers so the PWM frequency can be set
differently for each individual PWM channel.

Include

To use this procedure, include the library:

include pwm_common

Parameters

  • prescaler - byte in

Return Value

None

Example

From sample file: 18f4525_servo_rc_slave.jal

-- Title: RC Servo Slave sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows your PIC to read pulses given by a RC
--              receiver. Connect your PIC to a rc receiver the same way you
--              would connect a RC servo. This will use the rc_servo_slave
--              library to output a value to the serial port dependant on
--              where your fingers are moving the controls on your remote
--              transmitter. PIC will read the pulse width at the receiver.
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B. If you are using another
-- port, INTCON_RBIE & INTCON_RBIF may be named differently.
-- Check your datasheet for a interrupt-on-change pin.
--
-- Connect clock_out pin directly to int_on_change pin for an example without
-- an actual RC receiver.
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- choose pins to use for interrupt on change
const byte int_on_change_pins[] = {"B",4,"B",5} -- interrupt on change pin 0 and 1,  B4 and B5
include interrupt_on_change
int_on_change_init()

-- setup servo slave lib
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_0 = TRUE -- use interrupt on change pin 0
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_1 = TRUE -- use interrupt on change pin 1
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_2 = 0 -- use interrupt on change pin 2
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_3 = 0 -- use interrupt on change pin 3
--
const SERVO_SLAVE_USE_TIMER = 1     -- choose a timer
--
-- set your min/max values (0 to 100)
-- adjust SERVO_SLAVE_MIN first, then adjust SERVO_SLAVE_MAX
-- so output values will range from 0 to 255.
const SERVO_SLAVE_MIN = 0 -- default is 0
const SERVO_SLAVE_MAX = 0 -- default is 0
--
include servo_rc_slave
servo_slave_init()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on() -- turn on PWM1
pwm2_on() -- turn on PWM1

-- define clock out pin
alias clock_out           is pin_a1
alias clock_out_direction is pin_a1_direction
clock_out_direction = output

-- main loop
forever loop
   -- create a pulse to measure
   -- if your receiver is not connected, you may use this signal.
   clock_out = high
   _usec_delay(1500) -- 500 to 2_500 (0.5ms to 2.5ms)
   clock_out = low
   _usec_delay(20_000)

   -- SIGNAL 1
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[0] == TRUE then
      -- set the led brightness
      pwm1_set_dutycycle_ratio( servo_slave[0] << 2)
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[0])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm1_set_dutycycle_ratio(0) -- turn led off
   end if

   serial_data = " "
   serial_data = "-"
   serial_data = " "

   -- SIGNAL 2
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[1] == TRUE then
      -- set the led brightness
      pwm2_set_dutycycle_ratio( servo_slave[1] << 2 )
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[1])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm2_set_dutycycle_ratio(1) -- turn led off
   end if

   -- send crlf to serial port
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: pwm_common.jal


pwm_pwm1.jal - JALLIB Library Documentation

pwm_pwm1.jal JALLIB LIBRARY

Title

Hardware PWM control, supports 10-bit PWM and 16-bit PWM for module PWM1.

Author

Stef Mientki, Copyright (C) 2002..2024, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM1 module. This file is automatically
included by pwm_hardware.jal when the target PIC and supports
10-bit and 16-bit PWM.

Notes

Modelled after the libraries for CCP modules. Deprecated functions removed.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm1_set_dutycycle - Procedure
  • pwm1_get_resolution - Function returns word
  • pwm1_max_resolution - Procedure
  • pwm1_off - Procedure
  • pwm1_off - Procedure
  • pwm1_on - Procedure
  • pwm1_on - Procedure
  • pwm1_set_dutycycle_percent - Procedure
  • pwm1_set_dutycycle_percent - Procedure
  • pwm1_set_dutycycle_ratio - Procedure
  • pwm1_set_dutycycle_ratio - Procedure
  • pwm1_set_frequency - Procedure


pwm_pwm2.jal - JALLIB Library Documentation

pwm_pwm2.jal JALLIB LIBRARY

Title

Hardware PWM control, supports 10-bit PWM and 16-bit PWM for module PWM2.

Author

Stef Mientki, Copyright (C) 2002..2024, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM2 module. This file is automatically
included by pwm_hardware.jal when the target PIC and supports
10-bit and 16-bit PWM.

Notes

Modelled after the libraries for CCP modules. Deprecated functions removed.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm2_set_dutycycle - Procedure
  • pwm2_get_resolution - Function returns word
  • pwm2_max_resolution - Procedure
  • pwm2_off - Procedure
  • pwm2_off - Procedure
  • pwm2_on - Procedure
  • pwm2_on - Procedure
  • pwm2_set_dutycycle_percent - Procedure
  • pwm2_set_dutycycle_percent - Procedure
  • pwm2_set_dutycycle_ratio - Procedure
  • pwm2_set_dutycycle_ratio - Procedure
  • pwm2_set_frequency - Procedure


pwm_pwm3.jal - JALLIB Library Documentation

pwm_pwm3.jal JALLIB LIBRARY

Title

Hardware PWM control, supports 10-bit PWM and 16-bit PWM for module PWM2.

Author

Stef Mientki, Copyright (C) 2002..2024, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM3 module. This file is automatically
included by pwm_hardware.jal when the target PIC and supports
10-bit and 16-bit PWM.

Notes

Modelled after the libraries for CCP modules.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm3_set_dutycycle - Procedure
  • pwm3_get_resolution - Function returns word
  • pwm3_max_resolution - Procedure
  • pwm3_off - Procedure
  • pwm3_off - Procedure
  • pwm3_on - Procedure
  • pwm3_on - Procedure
  • pwm3_set_dutycycle_percent - Procedure
  • pwm3_set_dutycycle_percent - Procedure
  • pwm3_set_dutycycle_ratio - Procedure
  • pwm3_set_dutycycle_ratio - Procedure
  • pwm3_set_frequency - Procedure


pwm_pwm4.jal - JALLIB Library Documentation

pwm_pwm4.jal JALLIB LIBRARY

Title

Hardware PWM control, supports 10-bit PWM and 16-bit PWM for module PWM4.

Author

Stef Mientki, Copyright (C) 2002..2024, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM3 module. This file is automatically
included by pwm_hardware.jal when the target PIC and supports
10-bit and 16-bit PWM.

Notes

Modelled after the libraries for CCP modules.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm4_set_dutycycle - Procedure
  • pwm4_get_resolution - Function returns word
  • pwm4_max_resolution - Procedure
  • pwm4_off - Procedure
  • pwm4_off - Procedure
  • pwm4_on - Procedure
  • pwm4_on - Procedure
  • pwm4_set_dutycycle_percent - Procedure
  • pwm4_set_dutycycle_percent - Procedure
  • pwm4_set_dutycycle_ratio - Procedure
  • pwm4_set_dutycycle_ratio - Procedure
  • pwm4_set_frequency - Procedure


pwm_pwm5.jal - JALLIB Library Documentation

pwm_pwm5.jal JALLIB LIBRARY

Title

hardware PWM control, supports 10-bit PTM and 16-bit PWM for module PWM5.

Author

Rob Jansen, Copyright (C) 2022..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM5 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM5 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm5_set_dutycycle_highres - Procedure
  • pwm5_get_resolution - Function returns word
  • pwm5_max_resolution - Procedure
  • pwm5_off - Procedure
  • pwm5_off - Procedure
  • pwm5_on - Procedure
  • pwm5_on - Procedure
  • pwm5_set_dutycycle - Procedure
  • pwm5_set_dutycycle - Procedure
  • pwm5_set_dutycycle_lowres - Procedure
  • pwm5_set_dutycycle_lowres - Procedure
  • pwm5_set_dutycycle_percent - Procedure
  • pwm5_set_dutycycle_percent - Procedure
  • pwm5_set_dutycycle_ratio - Procedure
  • pwm5_set_dutycycle_ratio - Procedure
  • pwm5_set_frequency - Procedure


pwm_pwm6.jal - JALLIB Library Documentation

pwm_pwm6.jal JALLIB LIBRARY

Title

Hardware PWM control, supports 10-bit PWM and 16-bit PWM for module PWM6.

Author

Rob Jansen, Copyright (C) 2022..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM6 module. This file is automatically
included by pwm_hardware.jal when the target PIC and supports
10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm6_set_dutycycle_highres - Procedure
  • pwm6_get_resolution - Function returns word
  • pwm6_max_resolution - Procedure
  • pwm6_off - Procedure
  • pwm6_off - Procedure
  • pwm6_on - Procedure
  • pwm6_on - Procedure
  • pwm6_set_dutycycle - Procedure
  • pwm6_set_dutycycle - Procedure
  • pwm6_set_dutycycle_lowres - Procedure
  • pwm6_set_dutycycle_lowres - Procedure
  • pwm6_set_dutycycle_percent - Procedure
  • pwm6_set_dutycycle_percent - Procedure
  • pwm6_set_dutycycle_ratio - Procedure
  • pwm6_set_dutycycle_ratio - Procedure
  • pwm6_set_frequency - Procedure


pwm_pwm7.jal - JALLIB Library Documentation

pwm_pwm7.jal JALLIB LIBRARY

Title

Hardware PWM control, support 10-bit PWM and 16-bit PWM for module PWM7.

Author

Rob Jansen, Copyright (C) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM7 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM7 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm7_set_dutycycle_highres - Procedure
  • pwm7_get_resolution - Function returns word
  • pwm7_max_resolution - Procedure
  • pwm7_off - Procedure
  • pwm7_off - Procedure
  • pwm7_on - Procedure
  • pwm7_on - Procedure
  • pwm7_set_dutycycle - Procedure
  • pwm7_set_dutycycle - Procedure
  • pwm7_set_dutycycle_lowres - Procedure
  • pwm7_set_dutycycle_lowres - Procedure
  • pwm7_set_dutycycle_percent - Procedure
  • pwm7_set_dutycycle_percent - Procedure
  • pwm7_set_dutycycle_ratio - Procedure
  • pwm7_set_dutycycle_ratio - Procedure
  • pwm7_set_frequency - Procedure


pwm_pwm8.jal - JALLIB Library Documentation

pwm_pwm8.jal JALLIB LIBRARY

Title

Hardware PWM control, support 10-bit PWM and 16-bit PWM for module PWM8.

Author

Rob Jansen, Copyright (C) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM8 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM8 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm8_set_dutycycle_highres - Procedure
  • pwm8_get_resolution - Function returns word
  • pwm8_max_resolution - Procedure
  • pwm8_off - Procedure
  • pwm8_off - Procedure
  • pwm8_on - Procedure
  • pwm8_on - Procedure
  • pwm8_set_dutycycle - Procedure
  • pwm8_set_dutycycle - Procedure
  • pwm8_set_dutycycle_lowres - Procedure
  • pwm8_set_dutycycle_lowres - Procedure
  • pwm8_set_dutycycle_percent - Procedure
  • pwm8_set_dutycycle_percent - Procedure
  • pwm8_set_dutycycle_ratio - Procedure
  • pwm8_set_dutycycle_ratio - Procedure
  • pwm8_set_frequency - Procedure


pwm_pwm9.jal - JALLIB Library Documentation

pwm_pwm9.jal JALLIB LIBRARY

Title

Hardware PWM control, support 10-bit PWM and 16-bit PWM for module PWM9.

Author

Rob Jansen, Copyright (C) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM9 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM9 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm9_set_dutycycle_highres - Procedure
  • pwm9_get_resolution - Function returns word
  • pwm9_max_resolution - Procedure
  • pwm9_off - Procedure
  • pwm9_off - Procedure
  • pwm9_on - Procedure
  • pwm9_on - Procedure
  • pwm9_set_dutycycle - Procedure
  • pwm9_set_dutycycle - Procedure
  • pwm9_set_dutycycle_lowres - Procedure
  • pwm9_set_dutycycle_lowres - Procedure
  • pwm9_set_dutycycle_percent - Procedure
  • pwm9_set_dutycycle_percent - Procedure
  • pwm9_set_dutycycle_ratio - Procedure
  • pwm9_set_dutycycle_ratio - Procedure
  • pwm9_set_frequency - Procedure


pwm_pwm10.jal - JALLIB Library Documentation

pwm_pwm10.jal JALLIB LIBRARY

Title

Hardware PWM control, support 10-bit PWM and 16-bit PWM for module PWM10.

Author

Rob Jansen, Copyright (C) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM10 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM10 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm10_set_dutycycle_highres - Procedure
  • pwm10_get_resolution - Function returns word
  • pwm10_max_resolution - Procedure
  • pwm10_off - Procedure
  • pwm10_off - Procedure
  • pwm10_on - Procedure
  • pwm10_on - Procedure
  • pwm10_set_dutycycle - Procedure
  • pwm10_set_dutycycle - Procedure
  • pwm10_set_dutycycle_lowres - Procedure
  • pwm10_set_dutycycle_lowres - Procedure
  • pwm10_set_dutycycle_percent - Procedure
  • pwm10_set_dutycycle_percent - Procedure
  • pwm10_set_dutycycle_ratio - Procedure
  • pwm10_set_dutycycle_ratio - Procedure
  • pwm10_set_frequency - Procedure


pwm_pwm11.jal - JALLIB Library Documentation

pwm_pwm11.jal JALLIB LIBRARY

Title

Hardware PWM control, support 10-bit PWM and 16-bit PWM for module PWM11.

Author

Rob Jansen, Copyright (C) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM11 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM11 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm11_set_dutycycle_highres - Procedure
  • pwm11_get_resolution - Function returns word
  • pwm11_max_resolution - Procedure
  • pwm11_off - Procedure
  • pwm11_off - Procedure
  • pwm11_on - Procedure
  • pwm11_on - Procedure
  • pwm11_set_dutycycle - Procedure
  • pwm11_set_dutycycle - Procedure
  • pwm11_set_dutycycle_lowres - Procedure
  • pwm11_set_dutycycle_lowres - Procedure
  • pwm11_set_dutycycle_percent - Procedure
  • pwm11_set_dutycycle_percent - Procedure
  • pwm11_set_dutycycle_ratio - Procedure
  • pwm11_set_dutycycle_ratio - Procedure
  • pwm11_set_frequency - Procedure


pwm_pwm12.jal - JALLIB Library Documentation

pwm_pwm12.jal JALLIB LIBRARY

Title

Hardware PWM control, support 10-bit PWM and 16-bit PWM for module PWM12.

Author

Rob Jansen, Copyright (C) 2024..2024, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Performs PWM operations on the PWM12 module. This file is automatically
included by pwm_hardware.jal when the target PIC has a PWM12 module.
The library supports 10-bit and 16-bit PWM.
-------------------------------------------------------------------------------------

======================== This code is for the 16-bit variant =======================

Routines

  • _pwm12_set_dutycycle_highres - Procedure
  • pwm12_get_resolution - Function returns word
  • pwm12_max_resolution - Procedure
  • pwm12_off - Procedure
  • pwm12_off - Procedure
  • pwm12_on - Procedure
  • pwm12_on - Procedure
  • pwm12_set_dutycycle - Procedure
  • pwm12_set_dutycycle - Procedure
  • pwm12_set_dutycycle_lowres - Procedure
  • pwm12_set_dutycycle_lowres - Procedure
  • pwm12_set_dutycycle_percent - Procedure
  • pwm12_set_dutycycle_percent - Procedure
  • pwm12_set_dutycycle_ratio - Procedure
  • pwm12_set_dutycycle_ratio - Procedure
  • pwm12_set_frequency - Procedure


pwm_set_frequency - JALlib Procedures Help

pwm_set_frequency JALLIB PROCEDURE

Signature

procedure pwm_set_frequency(dword in freq) is

Description

Purpose: Set all(!) CCP 10-bit modules for a specific PWM frequency.
Arguments: Input: dword - PWM frequency
Output: none
Notes: - User may check bit TIMER2_TMR2ON to see if call successful
TRUE: Timer2 ON, PWM frequency set
FALSE: Timer2 OFF, no PWM signal (frequency too high or too low
with current Fosc)
The minimum and maximum allowed PWM frequencies depend on the clock speed.
When specifying a value beyond the limits PWM will not be enabled.
.
The chosen frequency may enforce a limit on the PWM resolution (number of steps).
The application program should not specify a higher value for the duty cycle
than this limit. When exceeding this limit the dutycycle will probably result
in a 'weird' value.
Use the procedures pwm?_set_dutycycle_percent() and pwm?_set_dutycycle_ratio()
to set the desired duty cycle.

Include

To use this procedure, include the library:

include pwm_common

Parameters

  • freq - dword in

Return Value

None

Example

From sample file: 16f648a_pwm_sound.jal

-- Title: Test program for hardware (built-in) PWM. Plays sound
-- Author: Sebastien Lelong, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample show how to use PWM with a constant duty cycle and
-- a variable frequency. It plays a "nice" melody (connect a small piezzo)
-- Frequencies from 0 to 100_000Hz are played. At the beginning, no sound will come
-- the buzzer, because frequency is too low (no valid combination of PR2/T2CON)
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_pwm_sound.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

;@jallib section ccp
-- backlight control (can be variable and digital on this pin)
alias lcd_bl is pin_b3
alias lcd_bl_direction is pin_b3_direction
enable_digital_io()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
-- Let's go !!!
pwm1_on()

var dword counter = 0
forever loop

   for 100_000 using counter loop
      pwm_set_frequency(counter)
      -- Setting @50% gives max volume
      -- must be re-computed each time the frequency
      -- changes, because it depends on PR2 value
      pwm1_set_dutycycle_percent(50)
   end loop

end loop

Generated by JALlib CHM Help System | Source: pwm_common.jal


quadrature_counter_ls7366r.jal - JALLIB Library Documentation

quadrature_counter_ls7366r.jal JALLIB LIBRARY

Title

Quadrature Counter ls7366r

Author

Matthew Schinkel, copyright (c) 2017, all rights reserved., Adapted-by:

Compiler

2.4q6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

ls7366r is a quadrature encoder counter for counting or
keeping track of the position of a optical rotary encoder
or linear slide. This device can count signals of TTL type
(pulses 90 degrees out of phase) or signals with
up/down direction and clock signals. TTL mode is default
in this lib.

Notes

Use ls7366r_write(WRITE_MDR0, 0x00) after init() for
devices with up/down direction and count clock outputs (not tested).

Sources

https://lsicsi.com/datasheets/LS7366R.pdf

Count modes

Routines

  • ls7366r_init - Procedure
  • ls7366r_read - Function returns byte
  • ls7366r_read_counter - Function returns dword
  • ls7366r_reset - Procedure
  • ls7366r_write - Procedure


queue01.jal - JALLIB Library Documentation

queue01.jal JALLIB LIBRARY

Title

queue01 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue01 = x -- put x into queue; block if queue is full
x = queue01 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue01_nb_put()
and
queue01_nb_get()
--
other methods:
queue01_clear() -- clear queue (makes queue empty)
queue01_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue01_is_empty() -- returns true if queue is emtpy
queue01_is_full() -- returns true if queue is full
queue01_nr_free() -- returns nr of free places in queue
queue01_nr_used() -- returns nr of used places in queue
--
Option:
const queue01_element_size = n ; define Queue elements are n bytes wide (default is one byte)

Sources

queue size default

Constants and Variables

queue01_size - const byte = 10
queue01_element_size - const byte = 1
pntr - var byte
pntr - var byte

Routines

  • queue01'put - Procedure
  • queue01_clear - Procedure
  • queue01_empty - Function returns bit
  • queue01_is_empty - Function returns bit
  • queue01_is_full - Function returns bit
  • queue01_nb'put - Procedure
  • queue01_nb_get - Function returns bit
  • queue01_nb_put - Function returns bit
  • queue01_nr_free - Function returns byte
  • queue01_nr_used - Function returns byte


queue01_clear - JALlib Procedures Help

queue01_clear JALLIB PROCEDURE

Signature

procedure queue01_clear() is

Description

deprecated

Include

To use this procedure, include the library:

include queue01

Parameters

None

Return Value

None

Example

From sample file: 18f4550_i2c_hw_slave_eeprom_simulator.jal

-- Title: Test program for i2c hardware slave, message interface implementation
-- Author: Joep Suijs, Sebastien Lelong, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to implements an i2c hardware slave,
-- using the message interface lib. It has the same interface* as an 24lc256 i2c eeprom
-- and supports 32 bytes of memory. This means it can be used with the i2c master
-- samples: i2c_sw_l1 and i2c_hw_l1.
-- --
-- (* the slave does behave similar as far as the test is concerned. It does however
-- store the data in ram and the memory pointer behaves different, so read without
-- previous setting the desired address gives unpredictable results.)
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_i2c_hw_slave_eeprom_simulator.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog
;@jallib section led
-- LED IO definition
alias led is pin_b3
alias led_direction is pin_b3_direction
alias led2 is pin_b1
alias led2_direction is pin_b1_direction
led_direction = output

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

const byte str1[] = "Test i2c hardware slave - msg interface Eeprom sim interface.\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

-- for debug only!
-- const bit i2c_debug = true -- value does not care, the existence of the const enables debug
if(defined(i2c_debug) == true) then
   const byte  queue01_size = 80
   include queue01
   queue01_clear()
end if

-- ---------------
-- setup i2c slave
-- ---------------
const byte I2C_BUFFER_SIZE = 40
include i2c_hw_slave_msg

-- this will be the slave address. It looks like:
--     0b_0101_1100
-- => 0b_0101_110   : 7-bits address
-- =>            0  : 8th bit is to specify read or write operation.
--                    Value can be anything, it does not matter while init
const byte SLAVE_ADDRESS = 0xA0
i2c_hw_slave_init(SLAVE_ADDRESS)

-- simulated memory
var volatile byte memory[32];
var volatile word address_pointer = 0;

-- --------------------------------------------------------------------
-- i2c_process_message - User code for i2c slave
-- --------------------------------------------------------------------
-- This code is called from the ISR, every time the i2c slave module
-- received a serie of bytes.
-- The ISR logic assures this procedure is called exactly once for
-- each messagae.
-- --------------------------------------------------------------------
procedure i2c_process_message(byte in byte_count) is
   var byte i

   if (byte_count >= 2) then
      -- this should always be the case - we want at least a 2-byte address.
      address_pointer = word(i2c_buffer[0]) * 256 + word(i2c_buffer[1])

      if (byte_count > 2) then
         -- there are bytes to store
         i = 2
         for (byte_count - 2) loop

            if(defined(i2c_debug) == true) then
               queue01_nb = "&"
               print_byte_hex(queue01_nb, i2c_buffer[i])
            end if

            memory[(address_pointer & 0x1F)] = i2c_buffer[i]
            i = i + 1
            address_pointer = address_pointer + 1
         end loop
      end if

      -- now prepare buffer in case the master wants to read back
      for 32 using i loop
         i2c_buffer[i] = memory[((address_pointer + i)& 0x1F)]
      end loop
   end if

end procedure

-- blink a little to tell the world we're up
for 4 loop
   led = on
   _usec_delay(100000)
   led = off
   _usec_delay(100000)
end loop

var byte ch

-- just loop until interrupt is raised
forever loop

   if(defined(i2c_debug) == true) then
      -- dump data from isr to serial port
      ch = queue01_nb
      if (ch != 0) then serial_hw_data = ch end if
   end if

   if (serial_hw_read(ch) == true) then
      serial_hw_data = "!"
      for 32 using ch loop
         print_byte_hex(serial_hw_data, memory[ch])
         serial_hw_data = " "
      end loop
      print_crlf(serial_hw_data)
   end if

end loop

Generated by JALlib CHM Help System | Source: queue01.jal


queue01_nb_get - JALlib Procedures Help

queue01_nb_get JALLIB FUNCTION

Signature

function queue01_nb_get(byte*queue01_element_size out v) return bit is

Description

queue01_nb_get - get one byte from queue (non-blocking)
The byte read is put into v (calling param)
returns: true when we read a byte from the queue
false when the queue is empty (byte is not read from queue)

Include

To use this procedure, include the library:

include queue01

Parameters

  • v - byte*queue01_element_size out

Return Value

bit - Function return value

Example

From sample file: 18f14k50_queue.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for queue01.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_queue.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

-- set all IO as digital
enable_digital_io()

led_direction= output

const byte  queue01_size = 8
include queue01
queue01_clear()

var byte isr_put_counter = 0
var volatile byte test_mode

include delay

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

const byte str1[] = " - Test queue\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

var byte char, i

 forever loop
   delay_100ms( 2 )
;   LED = ! LED ; high
;   delay_100ms( 2 )
;   LED = low

   serial_hw_data = "."

   while (serial_hw_read(char)) loop
      case char of

         "0" : block
            test_mode = char - "0"

         end block

         "1" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - put 5 chars in queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 using i loop
               queue01 = i
               serial_hw_data = "0" | i
            end loop
         end block

        "2" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n2 - try to put 5 chars in queue (non-blocking)r\n"
            print_string(serial_hw_data, str11)

            for 5 using i loop
               serial_hw_data = "0" | i
               if (queue01_nb_put(i) == true) then
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
            end loop
         end block

         "3" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 loop
               i = queue01
               serial_hw_data = "0" | i
            end loop
         end block

         "4" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (non-blocking)\r\n"
            print_string(serial_hw_data, str11)

            for 5 loop
               if (queue01_nb_get(i) == true) then  -- get byte
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
               serial_hw_data = "0" | i             -- print byte
            end loop
         end block

         "8" : block
            test_mode = char - "0"
            const byte str11[] = "put "
            print_string(serial_hw_data, str11)

            var bit ret = queue01_nb_put(99)
            print_bit_logic(serial_hw_data, ret)

            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         "9" : block
            test_mode = char - "0"
            const byte str11[] = "get "
            print_string(serial_hw_data, str11)
            var bit ret = queue01_nb_get(i)
            print_bit_logic(serial_hw_data, ret)
            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         " " : block
            test_mode = char - "0"
            const byte str11[] = "free/used: "
            print_string(serial_hw_data, str11)
            var byte ret = queue01_nr_free()
            print_byte_dec(serial_hw_data, ret)
            serial_hw_data = "/"
            ret = queue01_nr_used()
            print_byte_dec(serial_hw_data, ret)
            print_crlf(serial_hw_data)

         end block

      end case
   end loop
end loop

Generated by JALlib CHM Help System | Source: queue01.jal


queue01_nb_put - JALlib Procedures Help

queue01_nb_put JALLIB FUNCTION

Signature

function queue01_nb_put(byte*queue01_element_size in v) return bit is

Description

queue01_nb_put - put one byte into queue (non-blocking)
return: true when the byte is put into the queue
false when the queue is full (byte is not put in queue)

Include

To use this procedure, include the library:

include queue01

Parameters

  • v - byte*queue01_element_size in

Return Value

bit - Function return value

Example

From sample file: 18f14k50_queue.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for queue01.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_queue.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

-- set all IO as digital
enable_digital_io()

led_direction= output

const byte  queue01_size = 8
include queue01
queue01_clear()

var byte isr_put_counter = 0
var volatile byte test_mode

include delay

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

const byte str1[] = " - Test queue\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

var byte char, i

 forever loop
   delay_100ms( 2 )
;   LED = ! LED ; high
;   delay_100ms( 2 )
;   LED = low

   serial_hw_data = "."

   while (serial_hw_read(char)) loop
      case char of

         "0" : block
            test_mode = char - "0"

         end block

         "1" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - put 5 chars in queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 using i loop
               queue01 = i
               serial_hw_data = "0" | i
            end loop
         end block

        "2" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n2 - try to put 5 chars in queue (non-blocking)r\n"
            print_string(serial_hw_data, str11)

            for 5 using i loop
               serial_hw_data = "0" | i
               if (queue01_nb_put(i) == true) then
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
            end loop
         end block

         "3" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 loop
               i = queue01
               serial_hw_data = "0" | i
            end loop
         end block

         "4" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (non-blocking)\r\n"
            print_string(serial_hw_data, str11)

            for 5 loop
               if (queue01_nb_get(i) == true) then  -- get byte
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
               serial_hw_data = "0" | i             -- print byte
            end loop
         end block

         "8" : block
            test_mode = char - "0"
            const byte str11[] = "put "
            print_string(serial_hw_data, str11)

            var bit ret = queue01_nb_put(99)
            print_bit_logic(serial_hw_data, ret)

            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         "9" : block
            test_mode = char - "0"
            const byte str11[] = "get "
            print_string(serial_hw_data, str11)
            var bit ret = queue01_nb_get(i)
            print_bit_logic(serial_hw_data, ret)
            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         " " : block
            test_mode = char - "0"
            const byte str11[] = "free/used: "
            print_string(serial_hw_data, str11)
            var byte ret = queue01_nr_free()
            print_byte_dec(serial_hw_data, ret)
            serial_hw_data = "/"
            ret = queue01_nr_used()
            print_byte_dec(serial_hw_data, ret)
            print_crlf(serial_hw_data)

         end block

      end case
   end loop
end loop

Generated by JALlib CHM Help System | Source: queue01.jal


queue01_nr_free - JALlib Procedures Help

queue01_nr_free JALLIB FUNCTION

Signature

function queue01_nr_free() return byte is

Description

queue01_nr_free - returns nr of free places in queue

Include

To use this procedure, include the library:

include queue01

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f14k50_queue.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for queue01.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_queue.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

-- set all IO as digital
enable_digital_io()

led_direction= output

const byte  queue01_size = 8
include queue01
queue01_clear()

var byte isr_put_counter = 0
var volatile byte test_mode

include delay

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

const byte str1[] = " - Test queue\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

var byte char, i

 forever loop
   delay_100ms( 2 )
;   LED = ! LED ; high
;   delay_100ms( 2 )
;   LED = low

   serial_hw_data = "."

   while (serial_hw_read(char)) loop
      case char of

         "0" : block
            test_mode = char - "0"

         end block

         "1" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - put 5 chars in queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 using i loop
               queue01 = i
               serial_hw_data = "0" | i
            end loop
         end block

        "2" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n2 - try to put 5 chars in queue (non-blocking)r\n"
            print_string(serial_hw_data, str11)

            for 5 using i loop
               serial_hw_data = "0" | i
               if (queue01_nb_put(i) == true) then
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
            end loop
         end block

         "3" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 loop
               i = queue01
               serial_hw_data = "0" | i
            end loop
         end block

         "4" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (non-blocking)\r\n"
            print_string(serial_hw_data, str11)

            for 5 loop
               if (queue01_nb_get(i) == true) then  -- get byte
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
               serial_hw_data = "0" | i             -- print byte
            end loop
         end block

         "8" : block
            test_mode = char - "0"
            const byte str11[] = "put "
            print_string(serial_hw_data, str11)

            var bit ret = queue01_nb_put(99)
            print_bit_logic(serial_hw_data, ret)

            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         "9" : block
            test_mode = char - "0"
            const byte str11[] = "get "
            print_string(serial_hw_data, str11)
            var bit ret = queue01_nb_get(i)
            print_bit_logic(serial_hw_data, ret)
            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         " " : block
            test_mode = char - "0"
            const byte str11[] = "free/used: "
            print_string(serial_hw_data, str11)
            var byte ret = queue01_nr_free()
            print_byte_dec(serial_hw_data, ret)
            serial_hw_data = "/"
            ret = queue01_nr_used()
            print_byte_dec(serial_hw_data, ret)
            print_crlf(serial_hw_data)

         end block

      end case
   end loop
end loop

Generated by JALlib CHM Help System | Source: queue01.jal


queue01_nr_used - JALlib Procedures Help

queue01_nr_used JALLIB FUNCTION

Signature

function queue01_nr_used() return byte is

Description

queue01_nr_used - returns nr of used places in queue

Include

To use this procedure, include the library:

include queue01

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f14k50_queue.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for queue01.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_queue.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

-- set all IO as digital
enable_digital_io()

led_direction= output

const byte  queue01_size = 8
include queue01
queue01_clear()

var byte isr_put_counter = 0
var volatile byte test_mode

include delay

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

const byte str1[] = " - Test queue\r\n"   -- define a string
print_string(serial_hw_data, str1)                 -- output string

var byte char, i

 forever loop
   delay_100ms( 2 )
;   LED = ! LED ; high
;   delay_100ms( 2 )
;   LED = low

   serial_hw_data = "."

   while (serial_hw_read(char)) loop
      case char of

         "0" : block
            test_mode = char - "0"

         end block

         "1" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - put 5 chars in queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 using i loop
               queue01 = i
               serial_hw_data = "0" | i
            end loop
         end block

        "2" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n2 - try to put 5 chars in queue (non-blocking)r\n"
            print_string(serial_hw_data, str11)

            for 5 using i loop
               serial_hw_data = "0" | i
               if (queue01_nb_put(i) == true) then
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
            end loop
         end block

         "3" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (blocking)\r\n"
            print_string(serial_hw_data, str11)
            for 5 loop
               i = queue01
               serial_hw_data = "0" | i
            end loop
         end block

         "4" : block
            test_mode = char - "0"
            const byte str11[] = "\r\n1 - get 5 chars from queue (non-blocking)\r\n"
            print_string(serial_hw_data, str11)

            for 5 loop
               if (queue01_nb_get(i) == true) then  -- get byte
                  serial_hw_data = "s" -- succes
               else
                  serial_hw_data = "f" -- fail
               end if
               serial_hw_data = "0" | i             -- print byte
            end loop
         end block

         "8" : block
            test_mode = char - "0"
            const byte str11[] = "put "
            print_string(serial_hw_data, str11)

            var bit ret = queue01_nb_put(99)
            print_bit_logic(serial_hw_data, ret)

            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         "9" : block
            test_mode = char - "0"
            const byte str11[] = "get "
            print_string(serial_hw_data, str11)
            var bit ret = queue01_nb_get(i)
            print_bit_logic(serial_hw_data, ret)
            serial_hw_data = "+"
            print_byte_dec(serial_hw_data, queue01_in_pointer)
            serial_hw_data = " "
            print_byte_dec(serial_hw_data, queue01_out_pointer)
            print_crlf(serial_hw_data)

         end block

         " " : block
            test_mode = char - "0"
            const byte str11[] = "free/used: "
            print_string(serial_hw_data, str11)
            var byte ret = queue01_nr_free()
            print_byte_dec(serial_hw_data, ret)
            serial_hw_data = "/"
            ret = queue01_nr_used()
            print_byte_dec(serial_hw_data, ret)
            print_crlf(serial_hw_data)

         end block

      end case
   end loop
end loop

Generated by JALlib CHM Help System | Source: queue01.jal


queue02.jal - JALLIB Library Documentation

queue02.jal JALLIB LIBRARY

Title

queue02 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue02 = x -- put x into queue; block if queue is full
x = queue02 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue02_nb_put()
and
queue02_nb_get()
--
other methods:
queue02_clear() -- clear queue (makes queue empty)
queue02_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue02_is_empty() -- returns true if queue is emtpy
queue02_is_full() -- returns true if queue is full
queue02_nr_free() -- returns nr of free places in queue
queue02_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue02_size - const byte = 10

Routines

  • queue02'get - Function returns byte
  • queue02'put - Procedure
  • queue02_clear - Procedure
  • queue02_empty - Function returns bit
  • queue02_is_empty - Function returns bit
  • queue02_is_full - Function returns bit
  • queue02_nb'get - Function returns byte
  • queue02_nb'put - Procedure
  • queue02_nb_get - Function returns bit
  • queue02_nb_put - Function returns bit
  • queue02_nr_free - Function returns byte
  • queue02_nr_used - Function returns byte


queue03.jal - JALLIB Library Documentation

queue03.jal JALLIB LIBRARY

Title

queue03 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue03 = x -- put x into queue; block if queue is full
x = queue03 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue03_nb_put()
and
queue03_nb_get()
--
other methods:
queue03_clear() -- clear queue (makes queue empty)
queue03_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue03_is_empty() -- returns true if queue is emtpy
queue03_is_full() -- returns true if queue is full
queue03_nr_free() -- returns nr of free places in queue
queue03_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue03_size - const byte = 10

Routines

  • queue03'get - Function returns byte
  • queue03'put - Procedure
  • queue03_clear - Procedure
  • queue03_empty - Function returns bit
  • queue03_is_empty - Function returns bit
  • queue03_is_full - Function returns bit
  • queue03_nb'get - Function returns byte
  • queue03_nb'put - Procedure
  • queue03_nb_get - Function returns bit
  • queue03_nb_put - Function returns bit
  • queue03_nr_free - Function returns byte
  • queue03_nr_used - Function returns byte


queue04.jal - JALLIB Library Documentation

queue04.jal JALLIB LIBRARY

Title

queue04 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue04 = x -- put x into queue; block if queue is full
x = queue04 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue04_nb_put()
and
queue04_nb_get()
--
other methods:
queue04_clear() -- clear queue (makes queue empty)
queue04_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue04_is_empty() -- returns true if queue is emtpy
queue04_is_full() -- returns true if queue is full
queue04_nr_free() -- returns nr of free places in queue
queue04_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue04_size - const byte = 10

Routines

  • queue04'get - Function returns byte
  • queue04'put - Procedure
  • queue04_clear - Procedure
  • queue04_empty - Function returns bit
  • queue04_is_empty - Function returns bit
  • queue04_is_full - Function returns bit
  • queue04_nb'get - Function returns byte
  • queue04_nb'put - Procedure
  • queue04_nb_get - Function returns bit
  • queue04_nb_put - Function returns bit
  • queue04_nr_free - Function returns byte
  • queue04_nr_used - Function returns byte


queue05.jal - JALLIB Library Documentation

queue05.jal JALLIB LIBRARY

Title

queue05 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue05 = x -- put x into queue; block if queue is full
x = queue05 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue05_nb_put()
and
queue05_nb_get()
--
other methods:
queue05_clear() -- clear queue (makes queue empty)
queue05_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue05_is_empty() -- returns true if queue is emtpy
queue05_is_full() -- returns true if queue is full
queue05_nr_free() -- returns nr of free places in queue
queue05_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue05_size - const byte = 10

Routines

  • queue05'get - Function returns byte
  • queue05'put - Procedure
  • queue05_clear - Procedure
  • queue05_empty - Function returns bit
  • queue05_is_empty - Function returns bit
  • queue05_is_full - Function returns bit
  • queue05_nb'get - Function returns byte
  • queue05_nb'put - Procedure
  • queue05_nb_get - Function returns bit
  • queue05_nb_put - Function returns bit
  • queue05_nr_free - Function returns byte
  • queue05_nr_used - Function returns byte


queue06.jal - JALLIB Library Documentation

queue06.jal JALLIB LIBRARY

Title

queue06 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue06 = x -- put x into queue; block if queue is full
x = queue06 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue06_nb_put()
and
queue06_nb_get()
--
other methods:
queue06_clear() -- clear queue (makes queue empty)
queue06_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue06_is_empty() -- returns true if queue is emtpy
queue06_is_full() -- returns true if queue is full
queue06_nr_free() -- returns nr of free places in queue
queue06_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue06_size - const byte = 10

Routines

  • queue06'get - Function returns byte
  • queue06'put - Procedure
  • queue06_clear - Procedure
  • queue06_empty - Function returns bit
  • queue06_is_empty - Function returns bit
  • queue06_is_full - Function returns bit
  • queue06_nb'get - Function returns byte
  • queue06_nb'put - Procedure
  • queue06_nb_get - Function returns bit
  • queue06_nb_put - Function returns bit
  • queue06_nr_free - Function returns byte
  • queue06_nr_used - Function returns byte


queue07.jal - JALLIB Library Documentation

queue07.jal JALLIB LIBRARY

Title

queue07 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue07 = x -- put x into queue; block if queue is full
x = queue07 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue07_nb_put()
and
queue07_nb_get()
--
other methods:
queue07_clear() -- clear queue (makes queue empty)
queue07_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue07_is_empty() -- returns true if queue is emtpy
queue07_is_full() -- returns true if queue is full
queue07_nr_free() -- returns nr of free places in queue
queue07_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue07_size - const byte = 10

Routines

  • queue07'get - Function returns byte
  • queue07'put - Procedure
  • queue07_clear - Procedure
  • queue07_empty - Function returns bit
  • queue07_is_empty - Function returns bit
  • queue07_is_full - Function returns bit
  • queue07_nb'get - Function returns byte
  • queue07_nb'put - Procedure
  • queue07_nb_get - Function returns bit
  • queue07_nb_put - Function returns bit
  • queue07_nr_free - Function returns byte
  • queue07_nr_used - Function returns byte


queue08.jal - JALLIB Library Documentation

queue08.jal JALLIB LIBRARY

Title

queue08 - fifo queue (number 01 is the template)

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (one) byte fifo queue.
This queue is interrupt-safe in the sense that you can write to the queue from the interrupt and
read from the main program or vice versa without special precautions.
Reading (or writing) from both interrupt and main program might not work properly.
--
The basic interface is pseudo var:
queue08 = x -- put x into queue; block if queue is full
x = queue08 -- read x from queue; block if queue is empty
--
non-blocking access to the same queue is provided by
queue08_nb_put()
and
queue08_nb_get()
--
other methods:
queue08_clear() -- clear queue (makes queue empty)
queue08_empty() -- returns true if queue is emtpy (depricated, use queue1_is_empty())
queue08_is_empty() -- returns true if queue is emtpy
queue08_is_full() -- returns true if queue is full
queue08_nr_free() -- returns nr of free places in queue
queue08_nr_used() -- returns nr of used places in queue

Sources

queue size default

Constants and Variables

queue08_size - const byte = 10

Routines

  • queue08'get - Function returns byte
  • queue08'put - Procedure
  • queue08_clear - Procedure
  • queue08_empty - Function returns bit
  • queue08_is_empty - Function returns bit
  • queue08_is_full - Function returns bit
  • queue08_nb'get - Function returns byte
  • queue08_nb'put - Procedure
  • queue08_nb_get - Function returns bit
  • queue08_nb_put - Function returns bit
  • queue08_nr_free - Function returns byte
  • queue08_nr_used - Function returns byte


random.jal - JALLIB Library Documentation

random.jal JALLIB LIBRARY

Title

random

Author

Joep Suijs, Copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4i

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides a (decent) random function.
The formula is provided by *the* George Marsaglia.
(see http://coding.derkeiler.com/Archive/C_CPP/comp.lang.c/2008-03/msg03691.html)
--
/* initialize with any 32-bit seed x and any 32-bit y not 0 */
static unsigned long x=2282008, y=362436069;
#define sK ( x=69069*x+123, y^=y<<13, y^=y>>17, y^=y<<5, x+y )
--
function random_byte returns an 8-bit random number
function random_word returns a 16-bit random number
functon dice returns a number from 1 to 6
--
Note: this library will recreate the same sequence. If this is undesired, assign a
different (non-zero!) startup-value to _rndx and/or _rndy at startup.
--
Note2: If you don't care about random quality and want to save a few processor cycles or
memory bytes, define random_downgrade to select a basic random algorithm.

Sources

Interface Copyright (C) 2005 Stef Mientki

Routines

  • dice - Function returns byte
  • random_byte - Function returns byte
  • random_word - Function returns word


random_byte - JALlib Procedures Help

random_byte JALLIB FUNCTION

Signature

function random_byte() return byte is

Description

random_byte - return an 8-bit random number

Include

To use this procedure, include the library:

include random

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f88_random.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for random.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f88_js.jal
--    * test : test_random.jal
--

;@jallib section chipdef
-- chip setup
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       enabled        -- allow low-voltage programming
pragma target CCP1MUX   pin_B3         -- ccp1 pin on B3

--
-- This setup uses the internal oscillator
;pragma target OSC       INTOSC_NOCLKOUT   -- internal oscillator
;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   pin_B3            -- ccp1 pin on B3
;OSCCON_IRCF = 7                           -- set prescaler to 1 (8 MHz)

;@jallib section led
-- LED IO definition
alias led             is pin_b3
alias led_direction   is pin_b3_direction
alias led2            is pin_b1
alias led2_direction  is pin_b1_direction
led_direction = output

include delay

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

include print

-- RANDOM --
-- The random provides a decent random function.
-- If you don't need proper random and need to save on memory
-- or cpu cycles, you could uncomment the line below. It will
-- save you 4 bytes of ram and about 80 bytes of program memory.
-- But: the random output will be of a much less quality!
;const random_downgrade = 1   -- if this constant exists (even with value 0),
                              -- the random functions are downgraded

-- include random lib
include random

var word tmp_word

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   for 100 loop
      -- print 100 random words
      tmp_word = random_word()  -- get 16-bit random number
      print_word_dec(serial_hw_data, tmp_word)
   end loop

   print_crlf(serial_hw_data)                      -- empty line
   print_byte_dec(serial_hw_data, random_byte())   -- get 8-bit random number and output it.
   print_crlf(serial_hw_data)

end loop

Generated by JALlib CHM Help System | Source: random.jal


random_word - JALlib Procedures Help

random_word JALLIB FUNCTION

Signature

function random_word() return word is

Description

random_word - return a 16-bit random number

Include

To use this procedure, include the library:

include random

Parameters

None

Return Value

word - Function return value

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: random.jal


rcos8 - JALlib Procedures Help

rcos8 JALLIB FUNCTION

Signature

function rcos8(sword in radius, sword in angle) return sword is

Description

Title: Obtain cosine value
Arguments: - radius (signed word)
- angle in degrees (signed word)
Returns: a signed word
Original: Michael Watterson
Notes: See with rsin8 function

Include

To use this procedure, include the library:

include math

Parameters

  • radius - sword in
  • angle - sword in

Return Value

None

Example

From sample file: 18f6310_glcd_ks0108_math.jal

-- ------------------------------------------------------
-- Title: Graphics LCD sample of the Microchip pic18f6310
--
-- Author: Rob Hamerling, Copyright (c) 2011..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample program for use with 128x64 graphics LCD
-- with KS0108 chipset, like the GDM12864A, using external fonts.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 18f6310

pragma target clock   20_000_000                   -- Fosc

pragma target OSC     hs
pragma target FCMEN   disabled
pragma target IESO    disabled
pragma target WDT     control
pragma target CCP2MUX pin_C1
pragma target MCLR    external
pragma target DEBUG   disabled

WDTCON_SWDTEN = OFF                       -- no watchdog

-- GRAPHIC_LCD IO definition ------------------------
var volatile byte GLCD_DATAPRT     is portD
var volatile byte GLCD_DATAPRT_DIR is portD_direction

var volatile bit GLCD_DI  is pin_E7
var volatile bit GLCD_RW  is pin_E3
var volatile bit GLCD_E   is pin_E5
var volatile bit GLCD_CS1 is pin_B0
var volatile bit GLCD_CS2 is pin_B1
var volatile bit GLCD_RST is pin_B2

var volatile bit GLCD_DI_DIRECTION  is pin_E7_direction
var volatile bit GLCD_RW_DIRECTION  is pin_E3_direction
var volatile bit GLCD_E_DIRECTION   is pin_E5_direction
var volatile bit GLCD_CS1_DIRECTION is pin_B0_direction
var volatile bit GLCD_CS2_DIRECTION is pin_B1_direction
var volatile bit GLCD_RST_DIRECTION is pin_B2_direction

const GLCD_CLIPPING = TRUE                         -- enable clipping (of ellipse)

enable_digital_io()                                -- all pins digital I/O

include delay
include math
include print

include glcd_6x8_font                              -- font to be used
include glcd_font                                  -- common font stuff
glcd_font_use(FONT_6X8)                            -- activate font

include glcd_ks0108                                -- glcd device dependent library
include glcd_common                                -- common glcd library

glcd_init()                                        -- initialize display

const byte str[] = "GLCD_TEST"

var byte  i
var byte  x,y
var sword dx,dy,r

forever loop

   glcd_clear_screen()
   delay_100ms(2)
   glcd_pen_color = GLCD_BLACK                     -- pixel color
   glcd_background_color = GLCD_WHITE              -- background color

   for GLCD_X_PIXELS using i loop                  -- sine wave
      dy = rsin8(sword(GLCD_Y_PIXELS / 2 - 1), sword(i) * 3)
      glcd_write_pixel(i, byte(GLCD_Y_PIXELS / 2 - dy))
      dy = rcos8(sword(GLCD_Y_PIXELS / 2 - 1), sword(i) * 3)
      glcd_write_pixel(i, byte(GLCD_Y_PIXELS / 2 - dy))
   end loop
   delay_100ms(20)

   glcd_clear_screen()
   delay_100ms(2)
   x = GLCD_X_PIXELS / 2                           -- x-coord. center
   y = GLCD_Y_PIXELS / 2                           -- y-coord. center
   r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius
   glcd_circle(x, y, byte(r) + 1)                  -- clock border
   for 60 using i loop                             -- 'minutes' of the
     polar_to_cartesian(r, sword(i) * 6 - 90, dx, dy)   -- delta-x, delta-y of hand
     glcd_pen_color = GLCD_BLACK
     glcd_line(x, y, byte(x + dx), byte(y + dy))   -- draw hand
     delay_100ms(3)
     glcd_pen_color = GLCD_WHITE
     glcd_line(x, y, byte(x + dx), byte(y + dy))   -- erase hand
   end loop
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: math.jal


rda5807m.jal - JALLIB Library Documentation

rda5807m.jal JALLIB LIBRARY

Title

Library for the RDA5807M FM RadioTuner.

Author

Rob Jansen, Copyright (c) 2023..2023, all rights reserved., Adapted-by:

Compiler

2.5r7

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for controlling the RDA5807M Radio Tuner.
The chip uses an IIC interface which must be defined by
the main program.

Notes

The main program has to define and include the used IIC library and
if needed define aliases to rule out differences between IIC
libraries. The chip operates at 3.3 Volt so make sure to use a level
shifter on the IIC lines if your PIC is running at 5 Volt.

-----------------------------------------------------------------------------
------------------ PUBLIC CONSTANTS & VARIABLES -----------------------------
-----------------------------------------------------------------------------

Band selection options.

Sources

Single-Chip Broadcast FM Radio Tuner Rev.1.8–Aug.2014

Constants and Variables

RDA5807M_BAND_US_EUROPE - const byte = 0 -- 87 .. 108 MHz.
87 .. 108 MHz.
RDA5807M_BAND_JAPAN - const byte = 1 -- 76 .. 91 MHz.
76 .. 91 MHz.
RDA5807M_BAND_WORLD_WIDE - const byte = 2 -- 76 .. 108 MHz.
76 .. 108 MHz.
RDA5807M_BAND_EAST_EUROPE - const byte = 3 -- 56 .. 67 or 50 .. 65 MHz.
56 .. 67 or 50 .. 65 MHz.
RDA5807M_SPACING_25_KHZ - const byte = 0
RDA5807M_SPACING_50_KHZ - const byte = 1
RDA5807M_SPACING_100_KHZ - const byte = 2 -- Used for Europe.
Used for Europe.
RDA5807M_SPACING_200_KHZ - const byte = 3
RDA5807M_DEEMPHASIS_50_US - const byte = 0 -- Used for Europe.
Used for Europe.
RDA5807M_DEEMPHASIS_75_US - const byte = 1
RDA5807M_VOLUME_MIN - const byte = 0
RDA5807M_VOLUME_MAX - const byte = 15
RDA5807M_RSSI_MIN - const byte = 0
RDA5807M_RSSI_MAX - const byte = 127
rda5807m_band_frequency_low - var dword
rda5807m_band_frequency_high - var dword

Routines

  • rda5807m_channel_has_rds - Function returns bit
  • rda5807m_channel_is_fm - Function returns bit
  • rda5807m_channel_is_ready - Function returns bit
  • rda5807m_channel_is_stereo - Function returns bit
  • rda5807m_disable_bass_boost - Procedure
  • rda5807m_disable_output - Procedure
  • rda5807m_disable_power - Procedure
  • rda5807m_disable_rds - Procedure
  • rda5807m_disable_soft_mute - Procedure
  • rda5807m_enable_bass_boost - Procedure
  • rda5807m_enable_output - Procedure
  • rda5807m_enable_power - Procedure
  • rda5807m_enable_rds - Procedure
  • rda5807m_enable_soft_mute - Procedure
  • rda5807m_get_frequency - Function returns dword
  • rda5807m_get_rds_data - Procedure
  • rda5807m_get_signal_strength - Function returns byte
  • rda5807m_init - Procedure
  • rda5807m_mute - Procedure
  • rda5807m_print_status - Procedure
  • rda5807m_read_register - Function returns word
  • rda5807m_seek_completed - Function returns bit
  • rda5807m_seek_down - Procedure
  • rda5807m_seek_stop - Procedure
  • rda5807m_seek_up - Procedure
  • rda5807m_set_band - Procedure
  • rda5807m_set_channel_spacing - Procedure
  • rda5807m_set_deemphasis - Procedure
  • rda5807m_set_frequency - Procedure
  • rda5807m_set_output_mono - Procedure
  • rda5807m_set_output_stereo - Procedure
  • rda5807m_set_volume - Procedure
  • rda5807m_unmute - Procedure
  • rda5807m_write_register - Procedure


rda5807m_channel_has_rds - JALlib Procedures Help

rda5807m_channel_has_rds JALLIB FUNCTION

Signature

function rda5807m_channel_has_rds() return bit is

Description

Returns TRUE when the selected channel has RDS. RDS must be enabled.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_channel_is_fm - JALlib Procedures Help

rda5807m_channel_is_fm JALLIB FUNCTION

Signature

function rda5807m_channel_is_fm() return bit is

Description

Returns TRUE when the selected channel is an FM station.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_channel_is_stereo - JALlib Procedures Help

rda5807m_channel_is_stereo JALLIB FUNCTION

Signature

function rda5807m_channel_is_stereo() return bit is

Description

Returns TRUE when the selected channel is stereo.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_disable_bass_boost - JALlib Procedures Help

rda5807m_disable_bass_boost JALLIB PROCEDURE

Signature

procedure rda5807m_disable_bass_boost() is

Description

Disable the bass boost off the RDA5807M.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_disable_soft_mute - JALlib Procedures Help

rda5807m_disable_soft_mute JALLIB PROCEDURE

Signature

procedure rda5807m_disable_soft_mute() is

Description

Disable soft mute off the RDA5807M.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_enable_output - JALlib Procedures Help

rda5807m_enable_output JALLIB PROCEDURE

Signature

procedure rda5807m_enable_output() is

Description

Enable the output of the RDA5807M.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_enable_rds - JALlib Procedures Help

rda5807m_enable_rds JALLIB PROCEDURE

Signature

procedure rda5807m_enable_rds() is

Description

Enable the RDS of the RDA5807M.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_get_frequency - JALlib Procedures Help

rda5807m_get_frequency JALLIB FUNCTION

Signature

function rda5807m_get_frequency() return dword is

Description

Get the frequency of the RDA5807M. The frequency is returned in kHz.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_get_rds_data - JALlib Procedures Help

rda5807m_get_rds_data JALLIB PROCEDURE

Signature

procedure rda5807m_get_rds_data(word out rdsa, word out rdsb,

Description

Get the RDS data. The channel must have RDS.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_get_signal_strength - JALlib Procedures Help

rda5807m_get_signal_strength JALLIB FUNCTION

Signature

function rda5807m_get_signal_strength() return byte is

Description

Get the RSSI signal strength of the current selected channel.
Return value is between RDA5807M_RSSI_MIN and RDA5807M_RSSI_MAX

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_init - JALlib Procedures Help

rda5807m_init JALLIB PROCEDURE

Signature

procedure rda5807m_init() is

Description

Intialize the RDA5807M. The device is initialized for Europe as follows:
-) Set the band to RDA5807M_BAND_US_EUROPE
-) Set the spacing to RDA5807M_SPACING_100_KHZ
-) Set the de-emphasis to RDA5807M_DEEMPHASIS_50_US
The device is reset and powered up.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_mute - JALlib Procedures Help

rda5807m_mute JALLIB PROCEDURE

Signature

procedure rda5807m_mute() is

Description

Mute the output off the RDA5807M.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_seek_completed - JALlib Procedures Help

rda5807m_seek_completed JALLIB FUNCTION

Signature

function rda5807m_seek_completed() return bit is

Description

Returns TRUE when a seek was completed.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_seek_up - JALlib Procedures Help

rda5807m_seek_up JALLIB PROCEDURE

Signature

procedure rda5807m_seek_up() is

Description

Seek up to the next channel.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_set_frequency - JALlib Procedures Help

rda5807m_set_frequency JALLIB PROCEDURE

Signature

procedure rda5807m_set_frequency(dword in frequency) is

Description

Set the frequency of the RDA5807M. The given frequency is given in kHz and
must be in the range of the selectded band.

Include

To use this procedure, include the library:

include rda5807m

Parameters

  • frequency - dword in

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_set_output_mono - JALlib Procedures Help

rda5807m_set_output_mono JALLIB PROCEDURE

Signature

procedure rda5807m_set_output_mono() is

Description

Set the output of the RDA5807M to mono.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_set_volume - JALlib Procedures Help

rda5807m_set_volume JALLIB PROCEDURE

Signature

procedure rda5807m_set_volume(byte in volume) is

Description

Set the volme of the RDA5870M. Volume must be in range RDA5807M_VOLUME_MIN
to RDA5807M_VOLUME_MAX.

Include

To use this procedure, include the library:

include rda5807m

Parameters

  • volume - byte in

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


rda5807m_unmute - JALlib Procedures Help

rda5807m_unmute JALLIB PROCEDURE

Signature

procedure rda5807m_unmute() is

Description

Unmute the output off the RDA5807M.

Include

To use this procedure, include the library:

include rda5807m

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rda5807m.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the RDA5807M FM Radio Tuner.
-- Author: Rob Jansen, Copyright (c) 2023..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r7
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the RDA5807M FM radio tuner.
--              The program wil tune to a preselected channel and will perform a
--              channel search through the FM band.
--              Information about the FM channel is sent to the serial port.
--
-- Notes: This chip operates at 3.3 Volt so make sure to use a level shifter
--        for the IIC pins if your PIC runs at 5.0 Volt
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(500_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
alias serial is serial_hw_data
include print
include delay

-- Settings for the IIC interface used by the RDA5870M.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias i2c_scl_direction is pin_C0_direction
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias i2c_sda_direction is pin_C1_direction
const word _i2c_bus_speed = 1 -- 100kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware

-- Include the FM Tuner library.
include rda5807m

-- Stereo LED.
alias stereo_led is pin_c3
pin_c3_direction = OUTPUT

-- -- Constants.
-- Your favorite radio station. Radio staito frequency is in kHz.
-- This is the frequency of Sky Radio in The Netherlands.
const dword RADIO_SKY = 101_600

-- -- Variables
var dword frequency -- In kHz.
var byte index

-- -- Procedures and Functions.

-- Print the given frequency in kHz and MHz.
procedure print_frequency(dword in frequency_value) is

   print_dword_dec(serial, frequency_value)
   print_string(serial, " kHz, or ")
   print_word_dec(serial, word(frequency_value / 1000))
   serial = "."
   print_word_dec(serial, word(frequency_value % 1000))
   print_string(serial, " MHz")

end procedure

-- Tune to the next FM channel and return TRUE when found.
-- Note that when the whole channel is done, it starts again
-- at the beginning of the channel.
function tune_to_next_channel() return bit is

   var bit channel_found = FALSE

   while !channel_found loop
      rda5807m_seek_up()
      -- Give the tuner some time to seek.
      _usec_delay(100_000)
      while !rda5807m_seek_completed() loop
         _usec_delay(10_000)
      end loop
      _usec_delay(200_000)
      -- One spacing seeked, see if there is an FM channel on this frequency.
      channel_found = rda5807m_channel_is_fm()
      print_string(serial, "Frequency: ")
      print_frequency(rda5807m_get_frequency)
      print_crlf(serial)
   end loop
   return channel_found

end function

-- Print the RDS info of this channel, if available.
procedure print_rds_info() is

   var word rdsa, rdsb, rdsc, rdsd

   if rda5807m_channel_has_rds() then
      print_string(serial, "RDS Info: ")
      rda5807m_get_rds_data(rdsa, rdsb, rdsc, rdsd)
      print_word_hex(serial, rdsa)
      serial = " "
      print_word_hex(serial, rdsb)
      serial = " "
      print_word_hex(serial, rdsc)
      serial = " "
      print_word_hex(serial, rdsd)
      print_crlf(serial)
   else
      print_string(serial, "This channel has no RDS.\r\n")
   end if

end procedure

-- Print the RSSI signal strength in percentage.
procedure print_signal_strength() is

   var word signal_strength

   signal_strength = word(rda5807m_get_signal_strength()) * 100
   signal_strength = signal_strength / word(RDA5807M_RSSI_MAX)
   print_string(serial, "Signal strength at ")
   print_byte_dec(serial, byte(signal_strength))
   print_string(serial, " %.\r\n")

end procedure

-- Main program.
stereo_led = LOW
-- Initialize the used libraries.
serial_hw_init()
i2c_initialize()
print_string(serial, "Initializing RDA5807M ... ")
rda5807m_init()

-- Do some additional settings.
rda5807m_set_output_mono()
rda5807m_disable_bass_boost()
rda5807m_enable_rds()
rda5807m_disable_soft_mute()
rda5807m_set_volume(10)
rda5807m_enable_output()
rda5807m_unmute()
print_string(serial, "done!\r\n")

forever loop

   -- Find the preselected radio channel.
   print_string(serial, "Tuning to my favorite radio station.\r\n")
   print_string(serial, "Frequency written to RDA5807M: ")
   print_frequency(RADIO_SKY)
   print_crlf(serial)
   -- Tune to this channel.
   rda5807m_set_frequency(RADIO_SKY)
   -- Give the tuner some time to seek to this channel.
   delay_1s(1)
   -- See if it did.
   print_string(serial, "Frequency read from RDA5807M: ")
   print_frequency(rda5807m_get_frequency)
   print_crlf(serial)
   if rda5807m_channel_is_fm() then
     print_string(serial, "This is an FM channel.\r\n")
   else
      print_string(serial, "This is not an FM channel.\r\n")
   end if
   print_crlf(serial)
   delay_1s(5)

   -- Now find all channels in this band.
   print_string(serial, "Channel search started.\r\n")
   -- Start from the beginning of the band.
   frequency = rda5807m_band_frequency_low
   rda5807m_set_frequency(rda5807m_band_frequency_low)
   -- Give the tuner some time to settle.
   delay_1ms(200)
   index = 1
   -- Stop when we did the whole band (it auto wraps to the start). Note that
   -- because of the auto wrap it finds the first channel twice.
   while (frequency >= rda5807m_get_frequency()) loop
      stereo_led = LOW
      -- Supress noise during search.
      rda5807m_mute()
      -- Find the next channel with FM.
      if tune_to_next_channel() then
         print_string(serial, "Channel ")
         print_byte_dec(serial, index)
         print_string(serial, " found!\r\n")
         index = index + 1
         -- If this channel is in stereo the stereo LED will be on.
         stereo_led = rda5807m_channel_is_stereo()
         -- If there is RDS info, print it. Wait some time before checking.
         -- since it takes time to get the RDS info.
         delay_1s(1)
         print_rds_info()
         -- Print the signal strength.
         print_signal_strength()
         -- Let's here the music.
         rda5807m_unmute()
         delay_1s(5)
      end if
      -- Store the current frequency.
      frequency = rda5807m_get_frequency()
   end loop
   print_string(serial, "Channel search done!\r\n\r\n")
   delay_1s(5)

end loop

Generated by JALlib CHM Help System | Source: rda5807m.jal


read_celsius_temp_sht - JALlib Procedures Help

read_celsius_temp_sht JALLIB PROCEDURE

Signature

procedure read_celsius_temp_sht(sbyte out celsius) is

Description

read Celcius temperature from SHT
with 1 C resolution, result is sbyte type, so -126...+127C
SHT takes 320 ms for measurement @ 14 bits
we will wait 400 ms
SHT may only be switched on for 10% of the time because of self-heating
so this measurement can only happen every four seconds!

Include

To use this procedure, include the library:

include temperature_sht

Parameters

  • celsius - sbyte out

Return Value

None

Example

From sample file: 16f876a_humidity_sht.jal

-- Title: test humidty values from Sensirion SHTxx humidity sensor, results on 4x20 LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the humidity values using the humidity_sht.jal library.
-- But the byte procedure with 1% RH precision and the word procedure with 0.01% RH precision are used.
-- Humidty is read every second: doing this every 500ms or faster heats the sensor, lowers the value,
-- so does not give accurate readings.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock     4_000_000            -- 4 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

include delay                                -- used by LCD lib and sht lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS           is pin_b5             -- LCD command/data select.
alias LCD_EN           is pin_b4             -- LCD data trigger
alias LCD_dataport     is portb_low          -- LCD data nibble
portb_direction        = all_output          -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting

alias SHT_DATA         is pin_a0             -- data in/out of SHTxx
alias SHT_DATA_DIR     is pin_a0_direction   -- fake-I2C requires bi-dir comms
alias SHT_SCK          is pin_a1             -- clock of SHTxx
pin_a1_direction       = output              -- pin_a4 needs pullup on some PICs
include humidity_sht                         -- library

-- -------------- VARIABLES ------------------------------

var byte humidity_8
var word humidity_16

var byte hum1, hum2, crc
var byte t1, t2

var sbyte temperature_7
var sword temperature_15

var byte counter

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
const byte str1[] = "Temperature and"
const byte str2[] = "humidity test."
const byte str3[] = "Sensirion SHT10"
const byte str4[] = "Thanks to jallib!"

lcd_cursor_position(0,0)
print_string(lcd, str1)
lcd_cursor_position(1,0)
print_string(lcd, str2)
lcd_cursor_position(2,0)
print_string(lcd, str3)
lcd_cursor_position(3,0)
print_string(lcd, str4)

delay_100ms(10)                              -- splash screen

lcd_clear_screen()

forever loop

   lcd_cursor_position(0, 0)              -- row 1, position = 1

   read_raw_hum_sht(hum1, hum2, crc)
   print_byte_hex(lcd, hum1)
   print_byte_hex(lcd, hum2)
   lcd = " "
   delay_1s(1)                              -- because of self-heating

   read_hum_sht(humidity_8)
   print_byte_dec(lcd, humidity_8)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   read_hum_word_sht(humidity_16)
   format_word_dec(lcd, humidity_16, 4, 2)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   lcd_cursor_position(1, 0)           -- row 2, position = 1

   read_raw_temp_sht(t1, t2, crc)      -- 320ms "on" time
   print_byte_hex(lcd, t1)
   print_byte_hex(lcd, t2)
   lcd = " "
   delay_1s(3)                         -- 3s off time, so no self-heating

   read_celsius_temp_sht(temperature_7)
   print_sbyte_dec(lcd, temperature_7)
   lcd = 0b1101_1111                   -- japanese char, resembles "degree" symbol
   lcd = "C"
   lcd = " "
   delay_1s(3)

   read_centicelsius_temp_sht(temperature_15)
   format_sword_dec(lcd, temperature_15, 5, 2)
   lcd = 0b1101_1111
   lcd = "C"
   lcd = " "
   lcd = " "
   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: temperature_sht.jal


read_centicelsius_temp_sht - JALlib Procedures Help

read_centicelsius_temp_sht JALLIB PROCEDURE

Signature

procedure read_centicelsius_temp_sht(sword out centicelsius) is

Description

read Celcius temperature from SHT
with 0.01 C resolution, result is sword type, so -327.68 .. +327.68 C
SHT takes 320 ms for measurement @ 14 bits
we will wait 400 ms
SHT may only be switched on for 10% of the time because of self-heating
so this measurement can only happen every four seconds!

Include

To use this procedure, include the library:

include temperature_sht

Parameters

  • centicelsius - sword out

Return Value

None

Example

From sample file: 16f876a_humidity_sht.jal

-- Title: test humidty values from Sensirion SHTxx humidity sensor, results on 4x20 LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the humidity values using the humidity_sht.jal library.
-- But the byte procedure with 1% RH precision and the word procedure with 0.01% RH precision are used.
-- Humidty is read every second: doing this every 500ms or faster heats the sensor, lowers the value,
-- so does not give accurate readings.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock     4_000_000            -- 4 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

include delay                                -- used by LCD lib and sht lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS           is pin_b5             -- LCD command/data select.
alias LCD_EN           is pin_b4             -- LCD data trigger
alias LCD_dataport     is portb_low          -- LCD data nibble
portb_direction        = all_output          -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting

alias SHT_DATA         is pin_a0             -- data in/out of SHTxx
alias SHT_DATA_DIR     is pin_a0_direction   -- fake-I2C requires bi-dir comms
alias SHT_SCK          is pin_a1             -- clock of SHTxx
pin_a1_direction       = output              -- pin_a4 needs pullup on some PICs
include humidity_sht                         -- library

-- -------------- VARIABLES ------------------------------

var byte humidity_8
var word humidity_16

var byte hum1, hum2, crc
var byte t1, t2

var sbyte temperature_7
var sword temperature_15

var byte counter

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
const byte str1[] = "Temperature and"
const byte str2[] = "humidity test."
const byte str3[] = "Sensirion SHT10"
const byte str4[] = "Thanks to jallib!"

lcd_cursor_position(0,0)
print_string(lcd, str1)
lcd_cursor_position(1,0)
print_string(lcd, str2)
lcd_cursor_position(2,0)
print_string(lcd, str3)
lcd_cursor_position(3,0)
print_string(lcd, str4)

delay_100ms(10)                              -- splash screen

lcd_clear_screen()

forever loop

   lcd_cursor_position(0, 0)              -- row 1, position = 1

   read_raw_hum_sht(hum1, hum2, crc)
   print_byte_hex(lcd, hum1)
   print_byte_hex(lcd, hum2)
   lcd = " "
   delay_1s(1)                              -- because of self-heating

   read_hum_sht(humidity_8)
   print_byte_dec(lcd, humidity_8)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   read_hum_word_sht(humidity_16)
   format_word_dec(lcd, humidity_16, 4, 2)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   lcd_cursor_position(1, 0)           -- row 2, position = 1

   read_raw_temp_sht(t1, t2, crc)      -- 320ms "on" time
   print_byte_hex(lcd, t1)
   print_byte_hex(lcd, t2)
   lcd = " "
   delay_1s(3)                         -- 3s off time, so no self-heating

   read_celsius_temp_sht(temperature_7)
   print_sbyte_dec(lcd, temperature_7)
   lcd = 0b1101_1111                   -- japanese char, resembles "degree" symbol
   lcd = "C"
   lcd = " "
   delay_1s(3)

   read_centicelsius_temp_sht(temperature_15)
   format_sword_dec(lcd, temperature_15, 5, 2)
   lcd = 0b1101_1111
   lcd = "C"
   lcd = " "
   lcd = " "
   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: temperature_sht.jal


read_hum_sht - JALlib Procedures Help

read_hum_sht JALLIB PROCEDURE

Signature

procedure read_hum_sht(byte out hum) is

Description

read humidity from SHT, result in byte precision 1%RH
SHT may only be switched on for 10% of the time because of self-heating
so this measurement can only happen every 500ms

Include

To use this procedure, include the library:

include temperature_sht

Parameters

  • hum - byte out

Return Value

None

Example

From sample file: 16f876a_humidity_sht.jal

-- Title: test humidty values from Sensirion SHTxx humidity sensor, results on 4x20 LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the humidity values using the humidity_sht.jal library.
-- But the byte procedure with 1% RH precision and the word procedure with 0.01% RH precision are used.
-- Humidty is read every second: doing this every 500ms or faster heats the sensor, lowers the value,
-- so does not give accurate readings.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock     4_000_000            -- 4 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

include delay                                -- used by LCD lib and sht lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS           is pin_b5             -- LCD command/data select.
alias LCD_EN           is pin_b4             -- LCD data trigger
alias LCD_dataport     is portb_low          -- LCD data nibble
portb_direction        = all_output          -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting

alias SHT_DATA         is pin_a0             -- data in/out of SHTxx
alias SHT_DATA_DIR     is pin_a0_direction   -- fake-I2C requires bi-dir comms
alias SHT_SCK          is pin_a1             -- clock of SHTxx
pin_a1_direction       = output              -- pin_a4 needs pullup on some PICs
include humidity_sht                         -- library

-- -------------- VARIABLES ------------------------------

var byte humidity_8
var word humidity_16

var byte hum1, hum2, crc
var byte t1, t2

var sbyte temperature_7
var sword temperature_15

var byte counter

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
const byte str1[] = "Temperature and"
const byte str2[] = "humidity test."
const byte str3[] = "Sensirion SHT10"
const byte str4[] = "Thanks to jallib!"

lcd_cursor_position(0,0)
print_string(lcd, str1)
lcd_cursor_position(1,0)
print_string(lcd, str2)
lcd_cursor_position(2,0)
print_string(lcd, str3)
lcd_cursor_position(3,0)
print_string(lcd, str4)

delay_100ms(10)                              -- splash screen

lcd_clear_screen()

forever loop

   lcd_cursor_position(0, 0)              -- row 1, position = 1

   read_raw_hum_sht(hum1, hum2, crc)
   print_byte_hex(lcd, hum1)
   print_byte_hex(lcd, hum2)
   lcd = " "
   delay_1s(1)                              -- because of self-heating

   read_hum_sht(humidity_8)
   print_byte_dec(lcd, humidity_8)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   read_hum_word_sht(humidity_16)
   format_word_dec(lcd, humidity_16, 4, 2)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   lcd_cursor_position(1, 0)           -- row 2, position = 1

   read_raw_temp_sht(t1, t2, crc)      -- 320ms "on" time
   print_byte_hex(lcd, t1)
   print_byte_hex(lcd, t2)
   lcd = " "
   delay_1s(3)                         -- 3s off time, so no self-heating

   read_celsius_temp_sht(temperature_7)
   print_sbyte_dec(lcd, temperature_7)
   lcd = 0b1101_1111                   -- japanese char, resembles "degree" symbol
   lcd = "C"
   lcd = " "
   delay_1s(3)

   read_centicelsius_temp_sht(temperature_15)
   format_sword_dec(lcd, temperature_15, 5, 2)
   lcd = 0b1101_1111
   lcd = "C"
   lcd = " "
   lcd = " "
   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: temperature_sht.jal


read_hum_word_sht - JALlib Procedures Help

read_hum_word_sht JALLIB PROCEDURE

Signature

procedure read_hum_word_sht(word out hum) is

Description

read humidity from SHT, result in word precision 0.01%RH
SHT may only be switched on for 10% of the time because of self-heating
so this measurement can only happen every 500ms

Include

To use this procedure, include the library:

include temperature_sht

Parameters

  • hum - word out

Return Value

None

Example

From sample file: 16f876a_humidity_sht.jal

-- Title: test humidty values from Sensirion SHTxx humidity sensor, results on 4x20 LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the humidity values using the humidity_sht.jal library.
-- But the byte procedure with 1% RH precision and the word procedure with 0.01% RH precision are used.
-- Humidty is read every second: doing this every 500ms or faster heats the sensor, lowers the value,
-- so does not give accurate readings.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock     4_000_000            -- 4 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

include delay                                -- used by LCD lib and sht lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS           is pin_b5             -- LCD command/data select.
alias LCD_EN           is pin_b4             -- LCD data trigger
alias LCD_dataport     is portb_low          -- LCD data nibble
portb_direction        = all_output          -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting

alias SHT_DATA         is pin_a0             -- data in/out of SHTxx
alias SHT_DATA_DIR     is pin_a0_direction   -- fake-I2C requires bi-dir comms
alias SHT_SCK          is pin_a1             -- clock of SHTxx
pin_a1_direction       = output              -- pin_a4 needs pullup on some PICs
include humidity_sht                         -- library

-- -------------- VARIABLES ------------------------------

var byte humidity_8
var word humidity_16

var byte hum1, hum2, crc
var byte t1, t2

var sbyte temperature_7
var sword temperature_15

var byte counter

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
const byte str1[] = "Temperature and"
const byte str2[] = "humidity test."
const byte str3[] = "Sensirion SHT10"
const byte str4[] = "Thanks to jallib!"

lcd_cursor_position(0,0)
print_string(lcd, str1)
lcd_cursor_position(1,0)
print_string(lcd, str2)
lcd_cursor_position(2,0)
print_string(lcd, str3)
lcd_cursor_position(3,0)
print_string(lcd, str4)

delay_100ms(10)                              -- splash screen

lcd_clear_screen()

forever loop

   lcd_cursor_position(0, 0)              -- row 1, position = 1

   read_raw_hum_sht(hum1, hum2, crc)
   print_byte_hex(lcd, hum1)
   print_byte_hex(lcd, hum2)
   lcd = " "
   delay_1s(1)                              -- because of self-heating

   read_hum_sht(humidity_8)
   print_byte_dec(lcd, humidity_8)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   read_hum_word_sht(humidity_16)
   format_word_dec(lcd, humidity_16, 4, 2)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   lcd_cursor_position(1, 0)           -- row 2, position = 1

   read_raw_temp_sht(t1, t2, crc)      -- 320ms "on" time
   print_byte_hex(lcd, t1)
   print_byte_hex(lcd, t2)
   lcd = " "
   delay_1s(3)                         -- 3s off time, so no self-heating

   read_celsius_temp_sht(temperature_7)
   print_sbyte_dec(lcd, temperature_7)
   lcd = 0b1101_1111                   -- japanese char, resembles "degree" symbol
   lcd = "C"
   lcd = " "
   delay_1s(3)

   read_centicelsius_temp_sht(temperature_15)
   format_sword_dec(lcd, temperature_15, 5, 2)
   lcd = 0b1101_1111
   lcd = "C"
   lcd = " "
   lcd = " "
   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: temperature_sht.jal


read_pcf8563 - JALlib Procedures Help

read_pcf8563 JALLIB PROCEDURE

Signature

procedure read_pcf8563(byte in ic_address,bit out integrity, byte out seconds, byte out minutes,

Description

Programme to read and control the PCF8563 real time IC
IC address is 0xA2
PCF8563 read sequence
1. Send a START condition and the slave address for write (A2h).
2. Set the address pointer to 2 (VL_seconds) by sending 02h.
3. Send a RESTART condition or STOP followed by START.
4. Send the slave address for read (A3h).
5. Read VL_seconds. 02
6. Read Minutes. 03
7. Read Hours. 04
8. Read Days. 05
9. Read Weekdays. 06
10. Read Century_months. 07
11. Read Years. 08
12. Send a STOP condition.

Include

To use this procedure, include the library:

include rtc_pcf8563

Parameters

None

Return Value

None

Example

From sample file: 16f877a_rtc_pcf8563.jal

-- ------------------------------------------------------
-- Title: Example program for RTC PCF8563.jal
--
-- Author: Andy Brooker, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by: (Joep Suijs)
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Example program for RTC PCF8563.jal
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--

-- chip setup
include 16f877a

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled
pragma target   WDT disabled

-- generic setup (see releated examples for more details);@jallib section serial
const serial_hw_baudrate = 9600
include serial_hardware
serial_hw_init()
include print
include format
include delay

;Hardware setup.
;First you have to setup the i2c bus hardware.
;The first thing to concider is if you can and want to use the MSSP to handle
;i2c (i2c hardware) or handle i2c in software.
;The first option - i2c hardware - is possible for most (but not all) PICs with MSSP.
;The advantage is that this option is generally faster then software i2c.
;If you choose i2c hardware, you will use the pre-defined i2c clock and i2c data pins. (scl and sda).
;With i2c in software, pick any free io pin for i2c clock and i2c data.
;
;Now you have choosen the pins, you need to setup the hardware.
;Connect clock, data and ground from the PIC to the i2c slave, place pull-up resistors
;(e.g. 1k5) from both clock and data to the pic power supply and power the slave device.
;For more details on this, check the i2c slave datasheet or look on the Internet.
;
;Software setup
;Now you have the hardware ready, you need to configure the software.
;
;First, define the pins used, for example on an 16F877a:

var volatile bit i2c_scl is pin_c3
var volatile bit i2c_scl_direction is pin_c3_direction
var volatile bit i2c_sda is pin_c4
var volatile bit i2c_sda_direction is pin_c4_direction

;Second, define the next two constants:
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true ; i2c levels (not SMB)

;And now you can include the 'level0' i2c library.
;This is the library that creates the i2c signals and comes in two flavors:

;include i2c_software
;i2c_initialize()

;or

include i2c_hardware
i2c_initialize()
;Both libraries have the same interface to send and receive bytes.

pin_d4_direction=output
alias led is pin_d4

pin_c0_direction=input
pin_c1_direction=input
pin_c2_direction=input

alias up is pin_c0
alias set is pin_c1
alias down is pin_c2

led = on
delay_100ms(50)
led = off

const byte str1[] = "Clock running OK"      -- define strings
const byte time[] = "Set Time?"
const byte date[] = "Set Day?"

const byte weekday0[] = "Sunday"    ; 0 0 0
const byte weekday1[] = "Monday"    ; 0 0 1
const byte weekday2[] = "Tuesday"   ; 0 1 0
const byte weekday3[] = "Wednesday" ; 0 1 1
const byte weekday4[] = "Thursday"  ; 1 0 0
const byte weekday5[] = "Friday"    ; 1 0 1
const byte weekday6[] = "Saturday"  ; 1 1 1

const byte month1[] = "January"  ; 0 0 0 0 1
const byte month2[] = "February" ; 0 0 0 1 0
const byte month3[] = "March"    ; 0 0 0 1 1
const byte month4[] = "April"    ; 0 0 1 0 0
const byte month5[] = "May"      ; 0 0 1 0 1
const byte month6[] = "June"     ; 0 0 1 1 0
const byte month7[] = "July"     ; 0 0 1 1 1
const byte month8[] = "August"   ; 0 1 0 0 0
const byte month9[] = "September"; 0 1 0 0 1
const byte month10[] = "October" ; 1 0 0 0 0
const byte month11[] = "November"; 1 0 0 0 1
const byte month12[] = "December"; 1 0 0 1 0

const byte extn1[] = "st"
const byte extn2[] = "nd"
const byte extn3[] = "rd"
const byte extn4[] = "th"

var byte i, d1, sec, min, hour, day, weekday, month, year, old_years
var byte char, char1, number_char
var byte extn[2]
var byte month_name[9]
var bit r, fail
var byte old_set

const byte pcf8563_address = 0xA2
const byte years = 20
include rtc_pcf8563

procedure display_weekday() is

   if weekday == 0 then print_string(serial_hw_data,weekday0) end if
   if weekday == 1 then print_string(serial_hw_data,weekday1) end if
   if weekday == 2 then print_string(serial_hw_data,weekday2) end if
   if weekday == 3 then print_string(serial_hw_data,weekday3) end if
   if weekday == 4 then print_string(serial_hw_data,weekday4) end if
   if weekday == 5 then print_string(serial_hw_data,weekday5) end if
   if weekday == 6 then print_string(serial_hw_data,weekday6) end if
   serial_hw_data = " "

end procedure

procedure display_day_of_month() is
   print_byte_dec(serial_hw_data,day)
   extn = extn4
   if day == 1 then extn = extn1 end if
   if day == 21 then extn = extn1 end if
   if day == 31 then extn = extn1 end if
   if day == 2 then extn = extn2 end if
   if day == 22 then extn = extn2 end if
   if day == 3 then extn = extn3 end if
   if day == 23 then extn = extn3 end if
   print_string(serial_hw_data,extn)
   serial_hw_data = " "
end procedure

procedure display_month() is
   if month == 1 then print_string(serial_hw_data,month1) end if
   if month == 2 then print_string(serial_hw_data,month2) end if
   if month == 3 then print_string(serial_hw_data,month3) end if
   if month == 4 then print_string(serial_hw_data,month4) end if
   if month == 5 then print_string(serial_hw_data,month5) end if
   if month == 6 then print_string(serial_hw_data,month6) end if
   if month == 7 then print_string(serial_hw_data,month7) end if
   if month == 8 then print_string(serial_hw_data,month8) end if
   if month == 9 then print_string(serial_hw_data,month9) end if
   if month == 10 then print_string(serial_hw_data,month10) end if
   if month == 11 then print_string(serial_hw_data,month11) end if
   if month == 12 then print_string(serial_hw_data,month12) end if
   serial_hw_data = " "
end procedure

procedure set_date() is

   old_set = weekday
   display_weekday()
   while set loop
      if !up then weekday = weekday + 1 end if
      if !down then weekday = weekday - 1 end if
      delay_100ms(3)
      if weekday > 6 then weekday = 0 end if
      if weekday == 255 then weekday = 6 end if
      if weekday != old_set then
         old_set = weekday
         display_weekday()
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x06,weekday)
   delay_100ms(10)

   old_set = day
   display_day_of_month()
   while set loop
      if !up then day = day + 1 end if
      if !down then day = day - 1 end if
      delay_100ms(3)
      if day > 31 then day = 1 end if
      if day == 0 then day = 31 end if
      if day != old_set then
         old_set = day
         display_day_of_month()
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x05,day)
   delay_100ms(10)

   old_set = month
   display_month()
   while set loop
      if !up then month = month + 1 end if
      if !down then month = month - 1 end if
      delay_100ms(3)
      if month == 13 then month = 1 end if
      if month == 0 then month = 12 end if
      if month != old_set then
         old_set = month
         display_month()
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x07,month)
   delay_100ms(10)

   old_set = year
   print_byte_dec(serial_hw_data,years)
   print_byte_dec(serial_hw_data,year)
   serial_hw_data = " "
   while set loop
      if !up then year = year + 1 end if
      if !down then year = year - 1 end if
      delay_100ms(3)
      if year == 100 then year = 0 end if
      if year == 255 then year = 99 end if
      if year != old_set then
         old_set = year
         print_byte_dec(serial_hw_data,year)
         serial_hw_data = " "
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x08,year)
   print_byte_dec(serial_hw_data,years)
   print_byte_dec(serial_hw_data,year)
   serial_hw_data = " "

end procedure

procedure set_time() is

   old_set = hour
   print_byte_dec(serial_hw_data,hour)
   serial_hw_data = " "
   delay_100ms(10)
   while set loop
      if !up then hour = hour + 1 end if
      if !down then hour = hour - 1 end if
      delay_100ms(3)
      if hour == 24 then hour = 0 end if
      if hour == 255 then hour = 23 end if
      if hour != old_set then
         old_set = hour
         print_byte_dec(serial_hw_data,hour)
         serial_hw_data = " "
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x04,hour)
   delay_100ms(10)
   old_set = min
   print_byte_dec(serial_hw_data,min)
   serial_hw_data = " "
   while set loop
      if !up then min = min + 1 end if
      if !down then min = min - 1 end if
      delay_100ms(3)
      if min == 60 then min = 0 end if
      if min == 255 then min = 59 end if
      if min != old_set then
         old_set = min
         print_byte_dec(serial_hw_data,min)
         serial_hw_data = " "
      end if
   end loop
   pcf8563_register_write(pcf8563_address,0x03,min)
   delay_100ms(10)
   old_set = sec
   while set loop
      if !up | !down then sec = 00 end if
      delay_100ms(3)
      format_time_hms(serial_hw_data,hour,min,sec)
      serial_hw_data = " "
      if sec != old_set then
         old_set = sec
         pcf8563_register_write(pcf8563_address,0x02,00)
      end if
   end loop
end procedure

; read time and date registers

procedure menu() is

   print_string(serial_hw_data, time)
   serial_hw_data = " "
   while down loop
      delay_100ms(3)
      if !up then
         set_time()
         print_string(serial_hw_data, time)
         serial_hw_data = " "
      end if
   end loop
   delay_100ms(10)

   print_string(serial_hw_data, date)
   serial_hw_data = " "
   while down loop
      delay_100ms(3)
      if !up then
         set_date()
         print_string(serial_hw_data, date)
         serial_hw_data = " "
      end if
   end loop
   delay_100ms(10)

;   while down loop
;       delay_100ms(3)
;      if !up then set_shack()
;   end loop

end procedure

forever loop

   if !set then menu() end if
   read_pcf8563(pcf8563_address,fail,sec,min,hour,day,month,weekday,year)

   if != fail then
      print_string(serial_hw_data, str1)
      serial_hw_data = " "
   end if

   format_time_hms(serial_hw_data,hour,min,sec)
   serial_hw_data = " "

   display_weekday()
   display_day_of_month()
   display_month()

   print_byte_dec(serial_hw_data,years)
   print_byte_dec(serial_hw_data,year)
   serial_hw_data = " "

   print_crlf(serial_hw_data)
   led = on
   delay_100ms(9)
   led = off

end loop

Generated by JALlib CHM Help System | Source: rtc_pcf8563.jal


read_raw_hum_sht - JALlib Procedures Help

read_raw_hum_sht JALLIB PROCEDURE

Signature

procedure read_raw_hum_sht(byte out MSB, byte out LSB, byte out CRC) is

Description

read raw 12-bit humidity from SHT
default value of resolution bit is 12 bit RH
SHT takes 55 ms for measurement @ 12 bits
we will wait 70 ms
SHT may only be switched on for 10% of the time because of self-heating
so this measurement can only happen every 500ms

Include

To use this procedure, include the library:

include temperature_sht

Parameters

  • MSB - byte out
  • LSB - byte out
  • CRC - byte out

Return Value

None

Example

From sample file: 16f876a_humidity_sht.jal

-- Title: test humidty values from Sensirion SHTxx humidity sensor, results on 4x20 LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the humidity values using the humidity_sht.jal library.
-- But the byte procedure with 1% RH precision and the word procedure with 0.01% RH precision are used.
-- Humidty is read every second: doing this every 500ms or faster heats the sensor, lowers the value,
-- so does not give accurate readings.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock     4_000_000            -- 4 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

include delay                                -- used by LCD lib and sht lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS           is pin_b5             -- LCD command/data select.
alias LCD_EN           is pin_b4             -- LCD data trigger
alias LCD_dataport     is portb_low          -- LCD data nibble
portb_direction        = all_output          -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting

alias SHT_DATA         is pin_a0             -- data in/out of SHTxx
alias SHT_DATA_DIR     is pin_a0_direction   -- fake-I2C requires bi-dir comms
alias SHT_SCK          is pin_a1             -- clock of SHTxx
pin_a1_direction       = output              -- pin_a4 needs pullup on some PICs
include humidity_sht                         -- library

-- -------------- VARIABLES ------------------------------

var byte humidity_8
var word humidity_16

var byte hum1, hum2, crc
var byte t1, t2

var sbyte temperature_7
var sword temperature_15

var byte counter

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
const byte str1[] = "Temperature and"
const byte str2[] = "humidity test."
const byte str3[] = "Sensirion SHT10"
const byte str4[] = "Thanks to jallib!"

lcd_cursor_position(0,0)
print_string(lcd, str1)
lcd_cursor_position(1,0)
print_string(lcd, str2)
lcd_cursor_position(2,0)
print_string(lcd, str3)
lcd_cursor_position(3,0)
print_string(lcd, str4)

delay_100ms(10)                              -- splash screen

lcd_clear_screen()

forever loop

   lcd_cursor_position(0, 0)              -- row 1, position = 1

   read_raw_hum_sht(hum1, hum2, crc)
   print_byte_hex(lcd, hum1)
   print_byte_hex(lcd, hum2)
   lcd = " "
   delay_1s(1)                              -- because of self-heating

   read_hum_sht(humidity_8)
   print_byte_dec(lcd, humidity_8)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   read_hum_word_sht(humidity_16)
   format_word_dec(lcd, humidity_16, 4, 2)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   lcd_cursor_position(1, 0)           -- row 2, position = 1

   read_raw_temp_sht(t1, t2, crc)      -- 320ms "on" time
   print_byte_hex(lcd, t1)
   print_byte_hex(lcd, t2)
   lcd = " "
   delay_1s(3)                         -- 3s off time, so no self-heating

   read_celsius_temp_sht(temperature_7)
   print_sbyte_dec(lcd, temperature_7)
   lcd = 0b1101_1111                   -- japanese char, resembles "degree" symbol
   lcd = "C"
   lcd = " "
   delay_1s(3)

   read_centicelsius_temp_sht(temperature_15)
   format_sword_dec(lcd, temperature_15, 5, 2)
   lcd = 0b1101_1111
   lcd = "C"
   lcd = " "
   lcd = " "
   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: temperature_sht.jal


read_raw_temp_sht - JALlib Procedures Help

read_raw_temp_sht JALLIB PROCEDURE

Signature

procedure read_raw_temp_sht(byte out MSB, byte out LSB, byte out CRC) is

Description

read raw 14-bit temperature from SHT
default value of resolution bit is 14 bit temperature
SHT takes 320 ms for measurement @ 14 bits
we will wait 330 ms
SHT may only be switched on for 10% of the time because of self-heating
so this measurement can only happen every two seconds!

Include

To use this procedure, include the library:

include temperature_sht

Parameters

  • MSB - byte out
  • LSB - byte out
  • CRC - byte out

Return Value

None

Example

From sample file: 16f876a_humidity_sht.jal

-- Title: test humidty values from Sensirion SHTxx humidity sensor, results on 4x20 LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008, all rights reserved.
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the humidity values using the humidity_sht.jal library.
-- But the byte procedure with 1% RH precision and the word procedure with 0.01% RH precision are used.
-- Humidty is read every second: doing this every 500ms or faster heats the sensor, lowers the value,
-- so does not give accurate readings.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock     4_000_000            -- 4 MHz xtal
pragma target OSC       HS                   -- high speed
pragma target WDT       disabled             -- no watchdog, please
pragma target LVP       enabled              -- allow low voltage programming

enable_digital_io()                          -- no analog pins used in this sample

include delay                                -- used by LCD lib and sht lib

const byte  LCD_ROWS = 4
const byte  LCD_CHARS = 20
alias LCD_RS           is pin_b5             -- LCD command/data select.
alias LCD_EN           is pin_b4             -- LCD data trigger
alias LCD_dataport     is portb_low          -- LCD data nibble
portb_direction        = all_output          -- LCD data is portb_low
include lcd_hd44780_4                        -- LCD library with 4 data lines
lcd_init()

include print                                -- nice formatted output
include format                               -- more nice formatting

alias SHT_DATA         is pin_a0             -- data in/out of SHTxx
alias SHT_DATA_DIR     is pin_a0_direction   -- fake-I2C requires bi-dir comms
alias SHT_SCK          is pin_a1             -- clock of SHTxx
pin_a1_direction       = output              -- pin_a4 needs pullup on some PICs
include humidity_sht                         -- library

-- -------------- VARIABLES ------------------------------

var byte humidity_8
var word humidity_16

var byte hum1, hum2, crc
var byte t1, t2

var sbyte temperature_7
var sword temperature_15

var byte counter

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()
const byte str1[] = "Temperature and"
const byte str2[] = "humidity test."
const byte str3[] = "Sensirion SHT10"
const byte str4[] = "Thanks to jallib!"

lcd_cursor_position(0,0)
print_string(lcd, str1)
lcd_cursor_position(1,0)
print_string(lcd, str2)
lcd_cursor_position(2,0)
print_string(lcd, str3)
lcd_cursor_position(3,0)
print_string(lcd, str4)

delay_100ms(10)                              -- splash screen

lcd_clear_screen()

forever loop

   lcd_cursor_position(0, 0)              -- row 1, position = 1

   read_raw_hum_sht(hum1, hum2, crc)
   print_byte_hex(lcd, hum1)
   print_byte_hex(lcd, hum2)
   lcd = " "
   delay_1s(1)                              -- because of self-heating

   read_hum_sht(humidity_8)
   print_byte_dec(lcd, humidity_8)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   read_hum_word_sht(humidity_16)
   format_word_dec(lcd, humidity_16, 4, 2)
   lcd = "%"
   lcd = "R"
   lcd = "H"
   lcd = " "
   delay_1s(1)

   lcd_cursor_position(1, 0)           -- row 2, position = 1

   read_raw_temp_sht(t1, t2, crc)      -- 320ms "on" time
   print_byte_hex(lcd, t1)
   print_byte_hex(lcd, t2)
   lcd = " "
   delay_1s(3)                         -- 3s off time, so no self-heating

   read_celsius_temp_sht(temperature_7)
   print_sbyte_dec(lcd, temperature_7)
   lcd = 0b1101_1111                   -- japanese char, resembles "degree" symbol
   lcd = "C"
   lcd = " "
   delay_1s(3)

   read_centicelsius_temp_sht(temperature_15)
   format_sword_dec(lcd, temperature_15, 5, 2)
   lcd = 0b1101_1111
   lcd = "C"
   lcd = " "
   lcd = " "
   delay_1s(3)

end loop

Generated by JALlib CHM Help System | Source: temperature_sht.jal


reboot - JALlib Procedures Help

reboot JALLIB PROCEDURE

Signature

procedure reboot() is

Description

No description available.

Include

To use this procedure, include the library:

include reboot

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sd_card_minix_demo.jal

-- Title: Minix FS/OS demo based on 18F27J53, ov er SD-Card storage
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Minix demo. Explore Minix filesystem and perform actions
-- using some sort of *nix-like commands:
--    * ls   : list directories or file's details
--    * cd   : change directory
--    * fsck : show super-block details
--    * cat  : print file content
--    * dcat : "dev" cat, showing address details and content when changing
--    * $?   : print last errors
-- .
-- You can also open, seek, read, write and close files. This sample is ideal
-- if you want to explore Minix FS and understand how it works behind the scene
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: this sample is derived from Jaluino Bee's sample, where SD-Card is
-- on MSSP2. That's why it's using Peripheral Pin Select to map MSSP2 pins
--

include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable
enable_digital_io()

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- RP3 <-> /SS2
PPS_MAP_SS2IN = RP3
-- RP2 <-> SCK2
PPS_MAP_RP2 = PPS_SCK2
PPS_MAP_SCK2IN = RP2
-- RP5 <-> SDI2
PPS_MAP_SDI2 = RP5
-- RP6 <-> SDO2
PPS_MAP_RP6 = PPS_SDO2
-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b0_direction
alias pin_ss2 is pin_b0
alias pin_sdi2_direction is pin_b2_direction
alias pin_sdo2_direction is pin_b3_direction
alias pin_sck2_direction is pin_a5_direction

-- -----------------------------------------------------------------
-- configure SPI to use MSSP2 module
-- -----------------------------------------------------------------
include spi_master_hw2
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- setup the sd card SPI "Slave Select" pin
alias sd_chip_select is pin_ss2
alias sd_chip_select_direction is pin_ss2_direction
sd_chip_select_direction = output
sd_chip_select = high
-- Aliases used for generic access for SD-card, pointing to MSSP2 related procedures
-- (you could change these aliases to use MSSP1, or even SPI software)
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed

-- -----------------------------------------------------------------
-- setup the sd card library
-- -----------------------------------------------------------------
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
const bit SD_DELAY_AFTER_WRITE = TRUE
-- define which data carrier to use to access sd-card
alias spi_master is spi_master_hw2
include sd_card
sd_init()

-- Misc includes
include print
include delay
include jascii
include strings

-- -----------------------------------------------------------------
-- Configure serial comms. to interact with Minix FS, send commands
-- and read results
-- -----------------------------------------------------------------
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- -----------------------------------------------------------------
-- Configure MinixFS aliases. We need to specify here how to access
-- underlying storage (here, SD-Card)
-- -----------------------------------------------------------------
alias minix_start_read is sd_start_read
alias minix_stop_read is sd_stop_read
alias minix_start_write is sd_start_write
alias minix_stop_write is sd_stop_write
alias minix_data_byte is sd_data_byte -- get|put byte
-- Underlying storage (SD-Card) uses 512 bytes buffer
-- Minix will need to access it
alias minix_read_sector is sd_read_sector
alias minix_write_sector is sd_write_sector
alias minix_sector_buffer is sd_sector_buffer
-- how do we know when we reach end of storage sector ?
alias MINIX_STORAGE_SECTOR_SIZE is SD_BYTE_PER_SECTOR

-- how to interact with Minix OS ? Through our serial comms.
alias minix_print_carrier is serial_hw_data

-- include main library
include minixfs
-- this one declares usefull commands to use through a commandline
include minixfs_cmd

-- This implements "reboot" command...
procedure reboot() is
   asm goto 0x00
end procedure

-- Minix commands for REPL impl.
const byte MINIX_FSCK_CMD[] = "fsck\0"
const byte MINIX_DOLLARQ_CMD[] = "$?\0"
const byte MINIX_CAT_CMD[] = "cat\0"
const byte MINIX_DCAT_CMD[] = "dcat\0"
const byte MINIX_CD_CMD[] = "cd\0"
const byte MINIX_LS_CMD[] = "ls\0"
const byte MINIX_OPEN_READ_CMD[] = "openr\0"
const byte MINIX_OPEN_WRITE_CMD[] = "openw\0"
const byte MINIX_CLOSE_CMD[] = "close\0"
const byte MINIX_READ_CMD[] = "read\0"
const byte MINIX_WRITE_CMD[] = "write\0"
const byte MINIX_SEEK_CMD[] = "seek\0"
const byte MINIX_BLOCK_CMD[] = "block\0"
const byte MINIX_RAWREAD_CMD[] = "rread\0"
const byte MINIX_ALLOC_CMD[] = "alloc\0"
const byte MINIX_REBOOT_CMD[] = "reboot\0"

-- OK, let's go !
const byte WELCOME[] = "Welcome to Minix OS :)"
const byte PROMPT[] = "minix> "
const byte COMMAND_NOT_FOUND[] = "Command not found"
print_crlf(serial_hw_data)
print_string(serial_hw_data,WELCOME)
print_crlf(serial_hw_data)

-- some sort of "mount". We require MinixFS to perform some checks
-- during init (true)
minix_init(true)

var byte command[16]
var byte filename[MINIX_MAX_FILENANE_LEN]
var byte char
var byte i
-- This is our REPL: Read-Eval-Print-Loop
forever loop

   -- print prompt :)
   print_string(serial_hw_data,PROMPT)

   -- init to no command and no filename
   command[0] = 0
   filename[0] = 0

   -- read command
   i = 0
   while true  loop
      char = serial_hw_data
      -- echo
      serial_hw_data = char
      if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
         command[i] = ASCII_NULL -- NULL terminated string
         exit loop
      end if
      command[i] = char
      i = i + 1
   end loop

   -- read filename if necessary
   if char == ASCII_SP then
      i = 0
      while true  loop
         char = serial_hw_data
         -- echo
         serial_hw_data = char
         if char == ASCII_LF | char == ASCII_CR then
            filename[i] = ASCII_NULL -- NULL terminated string
            exit loop
         end if
         filename[i] = char
         i = i + 1
      end loop
   end if

   if char == ASCII_LF | char == ASCII_CR | char == ASCII_SP then
      print_crlf(serial_hw_data)
   end if

   if command[0] != ASCII_NULL then
      if string_compare(command,MINIX_FSCK_CMD) then
         minix_dev_print_super_block()
      elsif string_compare(command,MINIX_DOLLARQ_CMD) then
         minix_dev_print_error()
      elsif string_compare(command,MINIX_CD_CMD) then
         minix_cd(filename)
      elsif string_compare(command,MINIX_CAT_CMD) then
         minix_cat(filename)
      elsif string_compare(command,MINIX_DCAT_CMD) then
         minix_dev_cat(filename)
      elsif string_compare(command,MINIX_LS_CMD) then
         minix_ls(filename)
      elsif string_compare(command,MINIX_OPEN_READ_CMD) then
         minix_open(filename,MINIX_MODE_READ)
      elsif string_compare(command,MINIX_OPEN_WRITE_CMD) then
         minix_open(filename,MINIX_MODE_WRITE)
      elsif string_compare(command,MINIX_CLOSE_CMD) then
         minix_close()
      elsif string_compare(command,MINIX_READ_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_read()
            end loop
         else
            serial_hw_data = minix_read()
         end if
      elsif string_compare(command,MINIX_WRITE_CMD) then
         for count(filename) using i loop
            if filename[i] == 0 then
               exit loop
            end if
            minix_write(filename[i])
         end loop
      elsif string_compare(command,MINIX_SEEK_CMD) then
         minix_seek(string_to_dword(filename))
      elsif string_compare(command,MINIX_BLOCK_CMD) then
         minix_open_block(string_to_dword(filename))
      elsif string_compare(command,MINIX_RAWREAD_CMD) then
         if filename[0] != 0 then
            for string_to_dword(filename) loop
               serial_hw_data = minix_data_byte
            end loop
         else
            serial_hw_data = minix_data_byte
         end if
      elsif string_compare(command,MINIX_ALLOC_CMD) then
         print_dword_dec(serial_hw_data,minix_zone_alloc())
         print_crlf(serial_hw_data)
      elsif string_compare(command,MINIX_REBOOT_CMD) then
         reboot()
      else
         print_string(serial_hw_data,COMMAND_NOT_FOUND)
         print_crlf(serial_hw_data)
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: reboot.jal


reboot.jal - JALLIB Library Documentation

reboot.jal JALLIB LIBRARY

Title

reboot function.

Author

Alun Jones, Copyright (c) 2012..2012, all rights reserved.

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides a single procedure, reboot() which,
when run, will reboot the PIC. If USB is present, it will disable this
first and delay for 2 seconds, which should give any connected master to
register the disconnect.
.
N.B. Does not work on architectures that don't have a reset assembler
instruction. I've put in a check to report this.

Routines

  • reboot - Procedure


Records - JAL Language Syntax Reference

Records JALV2 SYNTAX

Syntax

RECORD

Description

Records are special types, composed of fields which are built-in types, arrays, and/or other records. These are defined with: Once defined, the RECORD identifier can be use anywhere a simple type can be used. Each individual field is accessed using '.'

Example

          RECORD eyeinfo IS
             BYTE left
             BYTE right
          END RECORD
          ;
          ; a record can be initialized on definition as follows:
          ;
          VAR eyeinfo eye = { 3, 4 }
          ;
          ; alternately, each field is accessed with the '.' operator:
          ;
          eye.left = 1
          eye.right = 2
          ;
          ; A more complex example. This sets eyes[0] to {1,2},
          ; eyes[1] to {3,4} and eyes[2] to {5,6}:
          ;
          VAR eyeinfo eyes[5] = { { 1, 2 }, { 3, 4 }, { 5, 6 } }
          ;
          ; Finally, nested records and arrays are supported
          ;
          RECORD face_r IS
             eyeinfo eyes
             BYTE nose
             BYTE freckels[5]
          END RECORD
          VAR face_r[5] = {
             { { 1,2 }, 3, {4, 5, 6, 7, 8} },
             { { 2,1 }, 3, {8, 7, 6, 5, 4} }
          }

Generated by JAL Syntax Documentation System | Source: DITA


REPEAT - JAL Language Syntax Reference

REPEAT JALV2 SYNTAX

Syntax

REPEAT

Description

statement_block [ EXIT LOOP ] UNTIL lexpr statement_block will be executed until lexpr evaluates to 1, or until [EXIT LOOP] is encountered.

Example

REPEAT
xx = READ_ADC
UNTIL (xx < 5)

Generated by JAL Syntax Documentation System | Source: DITA


rsin8 - JALlib Procedures Help

rsin8 JALLIB FUNCTION

Signature

function rsin8(sword in radius, sword in angle) return sword is

Description

Title: Obtain sine value
Arguments: - radius (signed word)
- angle in degrees (signed word)
Returns: signed word
Original: Michael Watterson
Notes: Sine values scaled to (256 * 1.0 - 1) for values above zero.
(i.e. add one to lookup if using table directly for other than zeroth Element)
apart from zero, all values are 1 less than actual
to allow storage in 1 byte each
.
0 to 90 degrees in 1 degree steps
8-bits resolution sin function R x Sin (angle) in degrees -32767 to +32767
Result can be same magnitude and opposite sign
.
Use to generate audio waves by changing angle at a fixed speed.
If using all 360 degrees in one degree steps, then frequency is step rate / 360
At nyquist frequency you only need 0 and 180 degrees, i.e. 1/2 sample rate.
If sample rate is 48kHz then for 12kHz you have only 4 samples,
i.e. 90 degree steps at 1.2kHz thus you use 9 degree steps.
1 degree steps is thus 133.33 Hz if step speed is 48KHz
PWM can be loaded via this lookup
Use 128 and add 127 to answer for 8 bit PWM
Use 512 and add 511 to answer for 10bit PWM
If summing two frequencies, peak value is twice,
so add as swords < 16383 and divide sum by 2!
works with fixed point numbers 256 = 1.0

Include

To use this procedure, include the library:

include math

Parameters

  • radius - sword in
  • angle - sword in

Return Value

None

Example

From sample file: 18f6310_glcd_ks0108_math.jal

-- ------------------------------------------------------
-- Title: Graphics LCD sample of the Microchip pic18f6310
--
-- Author: Rob Hamerling, Copyright (c) 2011..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample program for use with 128x64 graphics LCD
-- with KS0108 chipset, like the GDM12864A, using external fonts.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- chip setup
include 18f6310

pragma target clock   20_000_000                   -- Fosc

pragma target OSC     hs
pragma target FCMEN   disabled
pragma target IESO    disabled
pragma target WDT     control
pragma target CCP2MUX pin_C1
pragma target MCLR    external
pragma target DEBUG   disabled

WDTCON_SWDTEN = OFF                       -- no watchdog

-- GRAPHIC_LCD IO definition ------------------------
var volatile byte GLCD_DATAPRT     is portD
var volatile byte GLCD_DATAPRT_DIR is portD_direction

var volatile bit GLCD_DI  is pin_E7
var volatile bit GLCD_RW  is pin_E3
var volatile bit GLCD_E   is pin_E5
var volatile bit GLCD_CS1 is pin_B0
var volatile bit GLCD_CS2 is pin_B1
var volatile bit GLCD_RST is pin_B2

var volatile bit GLCD_DI_DIRECTION  is pin_E7_direction
var volatile bit GLCD_RW_DIRECTION  is pin_E3_direction
var volatile bit GLCD_E_DIRECTION   is pin_E5_direction
var volatile bit GLCD_CS1_DIRECTION is pin_B0_direction
var volatile bit GLCD_CS2_DIRECTION is pin_B1_direction
var volatile bit GLCD_RST_DIRECTION is pin_B2_direction

const GLCD_CLIPPING = TRUE                         -- enable clipping (of ellipse)

enable_digital_io()                                -- all pins digital I/O

include delay
include math
include print

include glcd_6x8_font                              -- font to be used
include glcd_font                                  -- common font stuff
glcd_font_use(FONT_6X8)                            -- activate font

include glcd_ks0108                                -- glcd device dependent library
include glcd_common                                -- common glcd library

glcd_init()                                        -- initialize display

const byte str[] = "GLCD_TEST"

var byte  i
var byte  x,y
var sword dx,dy,r

forever loop

   glcd_clear_screen()
   delay_100ms(2)
   glcd_pen_color = GLCD_BLACK                     -- pixel color
   glcd_background_color = GLCD_WHITE              -- background color

   for GLCD_X_PIXELS using i loop                  -- sine wave
      dy = rsin8(sword(GLCD_Y_PIXELS / 2 - 1), sword(i) * 3)
      glcd_write_pixel(i, byte(GLCD_Y_PIXELS / 2 - dy))
      dy = rcos8(sword(GLCD_Y_PIXELS / 2 - 1), sword(i) * 3)
      glcd_write_pixel(i, byte(GLCD_Y_PIXELS / 2 - dy))
   end loop
   delay_100ms(20)

   glcd_clear_screen()
   delay_100ms(2)
   x = GLCD_X_PIXELS / 2                           -- x-coord. center
   y = GLCD_Y_PIXELS / 2                           -- y-coord. center
   r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius
   glcd_circle(x, y, byte(r) + 1)                  -- clock border
   for 60 using i loop                             -- 'minutes' of the
     polar_to_cartesian(r, sword(i) * 6 - 90, dx, dy)   -- delta-x, delta-y of hand
     glcd_pen_color = GLCD_BLACK
     glcd_line(x, y, byte(x + dx), byte(y + dy))   -- draw hand
     delay_100ms(3)
     glcd_pen_color = GLCD_WHITE
     glcd_line(x, y, byte(x + dx), byte(y + dy))   -- erase hand
   end loop
   delay_100ms(10)

end loop

Generated by JALlib CHM Help System | Source: math.jal


rtc_alarm_1_flag - JALlib Procedures Help

rtc_alarm_1_flag JALLIB FUNCTION

Signature

function rtc_alarm_1_flag() return bit is

Description

Returns TRUE when the set alarm 1 time matches the current RTC time.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_alarm_2_flag - JALlib Procedures Help

rtc_alarm_2_flag JALLIB FUNCTION

Signature

function rtc_alarm_2_flag() return bit is

Description

Returns TRUE when the set alarm 2 time matches the current RTC time.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_bcd2bin - JALlib Procedures Help

rtc_bcd2bin JALLIB FUNCTION

Signature

function rtc_bcd2bin(byte in bcd) return byte is

Description

Convert one byte packed bcd to one byte binary.
input: byte with bcd data
output: none
returns: byte with binary value of bcd byte
notes: - A byte in bcd notation contains ((16 * tens) + ones).
To convert it to a binary value: subtract (6 * tens),
implemented as subtract (8*tens - 2*tens).
Algorithm is modelled after an assembler version of
Scott Dattalo at PicList (and only slightly less efficient!).

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • bcd - byte in

Return Value

byte - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_calc_dayofweek - JALlib Procedures Help

rtc_calc_dayofweek JALLIB FUNCTION

Signature

function rtc_calc_dayofweek(byte in yy, byte in mm, byte in dd) return byte is

Description

Title: Calculate day of the week
input: year, month, day-of-month in bcd noation
returns: day of week number in range 1..7 (1 is Sunday)

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • yy - byte in
  • mm - byte in
  • dd - byte in

Return Value

byte - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_calc_dayofyear - JALlib Procedures Help

rtc_calc_dayofyear JALLIB FUNCTION

Signature

function rtc_calc_dayofyear(byte in yy, byte in mm, byte in dd) return word is

Description

Title: calculate day of the year
input: year, month, day-of-month in bcd notation
returns: number of the day of this year (binary word 1..366)

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • yy - byte in
  • mm - byte in
  • dd - byte in

Return Value

word - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_calibrate - JALlib Procedures Help

rtc_calibrate JALLIB PROCEDURE

Signature

procedure rtc_calibrate(sbyte in calibration) is

Description

Calibrate the RTCC module.
input: calibration value
output: none
returns: nothing
note: Calibration value is a signed byte (-128..+127).
A negative value must be specified when the crystal is too fast.
See datasheet for the calculation of the amount.

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • calibration - sbyte in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_common.jal - JALLIB Library Documentation

rtc_common.jal JALLIB LIBRARY

Title

Common RealTime Clock routines and RTC user interface

Author

Rob Hamerling, Copyright (c) 2013..2015, all rights reserved, Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library with common code and data for all rtc libraries.
.
Supported values:
.
- Elementary values of date and time (and alarm):
* year: byte 00..99
* month: byte 01..12
* day of month: byte 01..31
* hour: byte 00..23
* minute: byte 00..59
* second: byte 00..59
.
- Derived values (in binary notation):
* day of the year: word 1..366
* day of the week: byte 1..7 (1 = Sunday)
* minute of the day: word 1..1440
* second of the hour: word 1..3600
* second of the day: byte*3 1..86400

Notes

- variables in bcd notation can be printed conveniently with print_..._hex()
-------------------------------------------------------------------------
Some device specific declarations
Each hardware specific part of the rtc libraries should identify itself
with a unique numeric value of constant RTC_HW.
-------------------------------------------------------------------------

Routines

  • rtc_bcd2bin - Function returns byte
  • rtc_bin2bcd - Function returns byte
  • rtc_calc_dayofweek - Function returns byte
  • rtc_calc_dayofyear - Function returns word
  • rtc_dayofmonth_bcd'get - Function returns byte
  • rtc_dayofmonth_bcd'put - Procedure
  • rtc_dayofmonth_bin'get - Function returns byte
  • rtc_dayofmonth_bin'put - Procedure
  • rtc_dayofweek'get - Function returns byte
  • rtc_dayofyear'get - Function returns word
  • rtc_get_date_bcd - Procedure
  • rtc_get_date_bin - Procedure
  • rtc_get_time_bcd - Procedure
  • rtc_get_time_bin - Procedure
  • rtc_hour_bcd'get - Function returns byte
  • rtc_hour_bcd'put - Procedure
  • rtc_hour_bin'get - Function returns byte
  • rtc_hour_bin'put - Procedure
  • rtc_minute_bcd'get - Function returns byte
  • rtc_minute_bcd'put - Procedure
  • rtc_minute_bin'get - Function returns byte
  • rtc_minute_bin'put - Procedure
  • rtc_minuteofday'get - Function returns word
  • rtc_month_bcd'get - Function returns byte
  • rtc_month_bcd'put - Procedure
  • rtc_month_bin'get - Function returns byte
  • rtc_month_bin'put - Procedure
  • rtc_second_bcd'get - Function returns byte
  • rtc_second_bcd'put - Procedure
  • rtc_second_bin'get - Function returns byte
  • rtc_second_bin'put - Procedure
  • rtc_secondofhour'get - Function returns word
  • rtc_set_date_bcd - Procedure
  • rtc_set_date_bin - Procedure
  • rtc_set_time_bcd - Procedure
  • rtc_set_time_bin - Procedure
  • rtc_year_bcd'get - Function returns byte
  • rtc_year_bcd'put - Procedure
  • rtc_year_bin'get - Function returns byte
  • rtc_year_bin'put - Procedure


rtc_disable_32_khz - JALlib Procedures Help

rtc_disable_32_khz JALLIB PROCEDURE

Signature

procedure rtc_disable_32_khz() is

Description

Disable the 32 kHz output pin.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_ds1302.jal - JALLIB Library Documentation

rtc_ds1302.jal JALLIB LIBRARY

Title

communication between rtc DS1302 chip and microcontroller

Author

Richard Zengerink, Copyright (c) 2008, all rights reserved, Adapted-by: Rob Hamerling (2013, 2015), refactoring.

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to handle DS1302 rtc chip

Notes

----------------------------------------------------------------------------
constants declarations
----------------------------------------------------------------------------

--- realtime clock hardware identification

Constants and Variables

rtc_reg_second_ - const byte = 0x80
rtc_reg_minute_ - const byte = 0x82
rtc_reg_hour_ - const byte = 0x84
rtc_reg_dayofmonth_ - const byte = 0x86
rtc_reg_month_ - const byte = 0x88
rtc_reg_dayofweek_ - const byte = 0x8A
rtc_reg_year_ - const byte = 0x8C
rtc_reg_protect_ - const byte = 0x8E
rtc_reg_trickle_ - const byte = 0x90
rtc_reg_burst_clock_ - const byte = 0xBE
rtc_reg_ram_ - const byte = 0xC0 -- first of 31 bytes
first of 31 bytes
rtc_reg_burst_ram_ - const byte = 0xFE

Routines

  • rtc_clock_pulse_ - Procedure
  • rtc_init - Procedure
  • rtc_read_byte_raw_ - Procedure
  • rtc_read_dayofmonth - Function returns byte
  • rtc_read_hour - Function returns byte
  • rtc_read_minute - Function returns byte
  • rtc_read_month - Function returns byte
  • rtc_read_protect - Function returns bit
  • rtc_read_reg_ - Procedure
  • rtc_read_second - Function returns byte
  • rtc_read_year - Function returns byte
  • rtc_start - Procedure
  • rtc_stop - Procedure
  • rtc_write_byte_raw_ - Procedure
  • rtc_write_dayofmonth - Procedure
  • rtc_write_hour - Procedure
  • rtc_write_minute - Procedure
  • rtc_write_month - Procedure
  • rtc_write_protect - Procedure
  • rtc_write_reg_ - Procedure
  • rtc_write_second - Procedure
  • rtc_write_year - Procedure


rtc_ds1307.jal - JALLIB Library Documentation

rtc_ds1307.jal JALLIB LIBRARY

Title

DS1307 / I2C read write & bcd routines.

Author

Jean-Bernard, Copyright (c) 2001...2011, all rights reserved., Adapted-by: Enzo SERAFINI,

Compiler

2.4p

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

DS1307 / I2C read write & bcd routines.
Some DS1307 registers
Second adress is 0x00 values 0-59
Minuts adress is 0x01 values 0-59
Hour adress is 0x02 values 0-12 or 0-24
Week day adress is 0x03 values 1-7
Month day adress is 0x04 values 01-28,29,30,31
Month adress is 0x05 values 1-12
Year adress is 0x06 values 0-99
for more details download the pec.sheet
http://pdfserv.maxim-ic.com/arpdf/DS1307.pdf

Routines

  • ds1307_init - Procedure
  • ds1307_read - Procedure
  • ds1307_write - Procedure


rtc_ds3231.jal - JALLIB Library Documentation

rtc_ds3231.jal JALLIB LIBRARY

Title

Library for the DS3231 Real Time Clock IC.

Author

Rob Jansen, Copyright (c) 2021..2023, all rights reserved., Adapted-by:

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for controlling the SD3231 Real Time Clock IC.
The chip uses an IIC interface. The library provides all
functions and procedures to support the rtc_common.jal library and
includes extra functions and procedures specific for the DS3231.
For all common rtc procedures and functions see rtc_common.jal.
This chip has a temperature sensor on board so a temperature
measurement is also included. Since this is not an rtc funtion
the prefix of the function starts with ds3231_ instead of rtc_.
The chip uses an IIC interface which must be defined and
initialised by the main program.

Sources

Maxim datasheet rtc. 19-5170; Rev 10; 3/15

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Alarm rates of alarm 1.

Constants and Variables

RTC_ALARM_1_ONCE_PER_SEC - const byte = 0
RTC_ALARM_1_SEC_MATCH - const byte = 1
RTC_ALARM_1_MIN_SEC_MATCH - const byte = 2
RTC_ALARM_1_HOUR_MIN_SEC_MATCH - const byte = 3
RTC_ALARM_1_DATE_HOUR_MIN_SEC_MATCH - const byte = 4
RTC_ALARM_1_DAY_HOUR_MIN_SEC_MATCH - const byte = 5
RTC_ALARM_2_ONCE_PER_MIN - const byte = 0
RTC_ALARM_2_MIN_MATCH - const byte = 1
RTC_ALARM_2_HOUR_MIN_MATCH - const byte = 2
RTC_ALARM_2_DATE_HOUR_MIN_MATCH - const byte = 3
RTC_ALARM_2_DAY_HOUR_MIN_MATCH - const byte = 4
RTC_SQUARE_WAVE_1_HZ - const byte = 0b0000_0000
RTC_SQUARE_WAVE_1_KHZ - const byte = 0b0000_1000
RTC_SQUARE_WAVE_4_KHZ - const byte = 0b0001_0000
RTC_SQUARE_WAVE_8_KHZ - const byte = 0b0001_1000
RTC_TIME_SECONDS_ADDRESS - const byte = 0x00
RTC_TIME_MINUTES_ADDRESS - const byte = 0x01
RTC_TIME_HOUR_ADDRESS - const byte = 0x02
RTC_TIME_DAY_ADDRESS - const byte = 0x03
RTC_TIME_DATE_ADDRESS - const byte = 0x04
RTC_TIME_MONTH_ADDRESS - const byte = 0x05
RTC_TIME_YEAR_ADDRESS - const byte = 0x06
RTC_ALARM_1_SECONDS_ADDRESS - const byte = 0x07
RTC_ALARM_1_MINUTES_ADDRESS - const byte = 0x08
RTC_ALARM_1_HOUR_ADDRESS - const byte = 0x09
RTC_ALARM_1_DAY_DATE_ADDRESS - const byte = 0x0A
RTC_ALARM_2_MINUTES_ADDRESS - const byte = 0x0B
RTC_ALARM_2_HOUR_ADDRESS - const byte = 0x0C
RTC_ALARM_2_DAY_DATE_ADDRESS - const byte = 0x0D
RTC_CONTROL_ADDRESS - const byte = 0x0E
RTC_STATUS_ADDRESS - const byte = 0x0F
RTC_AGING_ADDRESS - const byte = 0x10
RTC_TEMP_MSB_ADDRESS - const byte = 0x11
RTC_TEMP_LSB_ADDRESS - const byte = 0x12
RTC_IIC_WR_ADDRESS - const byte = 0b1101_0000
RTC_IIC_RD_ADDRESS - const byte = 0b1101_0001

Routines

  • clear_rtc_alarm_1_flag - Procedure
  • clear_rtc_alarm_2_flag - Procedure
  • ds3231_get_temperature - Function returns sword
  • rtc_alarm_1_flag - Function returns bit
  • rtc_alarm_2_flag - Function returns bit
  • rtc_disable_32_khz - Procedure
  • rtc_disable_alarm_1_interrupt - Procedure
  • rtc_disable_alarm_2_interrupt - Procedure
  • rtc_enable_32_khz - Procedure
  • rtc_enable_alarm_1_interrupt - Procedure
  • rtc_enable_alarm_2_interrupt - Procedure
  • rtc_get_alarm_1_time_bcd - Procedure
  • rtc_get_alarm_1_time_bin - Procedure
  • rtc_get_alarm_2_time_bcd - Procedure
  • rtc_get_alarm_2_time_bin - Procedure
  • rtc_init - Procedure
  • rtc_read_dayofmonth - Function returns byte
  • rtc_read_dayofweek - Function returns byte
  • rtc_read_full_year - Function returns word
  • rtc_read_hour - Function returns byte
  • rtc_read_minute - Function returns byte
  • rtc_read_month - Function returns byte
  • rtc_read_register - Procedure
  • rtc_read_second - Function returns byte
  • rtc_read_year - Function returns byte
  • rtc_set_alarm_1_date - Procedure
  • rtc_set_alarm_1_day - Procedure
  • rtc_set_alarm_1_rate - Procedure
  • rtc_set_alarm_1_time_bcd - Procedure
  • rtc_set_alarm_1_time_bin - Procedure
  • rtc_set_alarm_2_rate - Procedure
  • rtc_set_alarm_2_time_bcd - Procedure
  • rtc_set_alarm_2_time_bin - Procedure
  • rtc_set_square_wave - Procedure
  • rtc_start - Procedure
  • rtc_stop - Procedure
  • rtc_write_dayofmonth - Procedure
  • rtc_write_dayofweek - Procedure
  • rtc_write_full_year - Procedure
  • rtc_write_hour - Procedure
  • rtc_write_minute - Procedure
  • rtc_write_month - Procedure
  • rtc_write_register - Procedure
  • rtc_write_second - Procedure
  • rtc_write_year - Procedure


rtc_enable_32_khz - JALlib Procedures Help

rtc_enable_32_khz JALLIB PROCEDURE

Signature

procedure rtc_enable_32_khz() is

Description

Enable the 32 kHz output pin.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_enable_alarm_1_interrupt - JALlib Procedures Help

rtc_enable_alarm_1_interrupt JALLIB PROCEDURE

Signature

procedure rtc_enable_alarm_1_interrupt() is

Description

Enable alarm 1 interrupt.
Note: This will disable the square wave output on the INT/SQW pin.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_enable_alarm_2_interrupt - JALlib Procedures Help

rtc_enable_alarm_2_interrupt JALLIB PROCEDURE

Signature

procedure rtc_enable_alarm_2_interrupt() is

Description

Enable alarm 2 interrupt.
Note: This will disable the square wave output on the INT/SQW pin.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_get_alarm_1_time_bin - JALlib Procedures Help

rtc_get_alarm_1_time_bin JALLIB PROCEDURE

Signature

procedure rtc_get_alarm_1_time_bin(byte out hour, byte out minutes, byte out seconds) is

Description

Get alarm 1 time in hours, minutes and seconds in binary notation.
Hours must be in 24-hours format.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • hour - byte out
  • minutes - byte out
  • seconds - byte out

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_get_alarm_2_time_bin - JALlib Procedures Help

rtc_get_alarm_2_time_bin JALLIB PROCEDURE

Signature

procedure rtc_get_alarm_2_time_bin(byte out hour, byte out minutes) is

Description

Get alarm 2 time in hours and minutes in binary notation.
Hours must be in 24-hours format.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • hour - byte out
  • minutes - byte out

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_get_alarm_time_bcd - JALlib Procedures Help

rtc_get_alarm_time_bcd JALLIB PROCEDURE

Signature

procedure rtc_get_alarm_time_bcd(byte out hh, byte out mm, byte out ss) is

Description

Read alarm time
input: none
output: alarm hour, minute, second (bcd format)
returns: (nothing)
notes: read alarm registers into user variables

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • hh - byte out
  • mm - byte out
  • ss - byte out

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_get_date_bcd - JALlib Procedures Help

rtc_get_date_bcd JALLIB PROCEDURE

Signature

procedure rtc_get_date_bcd(byte out yy, byte out mm, byte out dd) is

Description

Title: get date (year, month, dayofmonth) in bcd notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • yy - byte out
  • mm - byte out
  • dd - byte out

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_get_date_bin - JALlib Procedures Help

rtc_get_date_bin JALLIB PROCEDURE

Signature

procedure rtc_get_date_bin(byte out yy, byte out mm, byte out dd) is

Description

Title: get date (year, month, dayofmonth) in binary notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • yy - byte out
  • mm - byte out
  • dd - byte out

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_get_time_bcd - JALlib Procedures Help

rtc_get_time_bcd JALLIB PROCEDURE

Signature

procedure rtc_get_time_bcd(byte out hh, byte out mm, byte out ss) is

Description

Title: get time (hour, minute, second) in bcd notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • hh - byte out
  • mm - byte out
  • ss - byte out

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_get_time_bin - JALlib Procedures Help

rtc_get_time_bin JALLIB PROCEDURE

Signature

procedure rtc_get_time_bin(byte out hh, byte out mm, byte out ss) is

Description

Title: get time (hour, minute, second) in binary notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • hh - byte out
  • mm - byte out
  • ss - byte out

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_init - JALlib Procedures Help

rtc_init JALLIB PROCEDURE

Signature

procedure rtc_init() is

Description

Intialize the rtc by initializing the IIC interface and setting the
clock to 24-hour mode and setting the year above the year 2000.
All the device interrupts will be disabled.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_isr_tmr0.jal - JALLIB Library Documentation

rtc_isr_tmr0.jal JALLIB LIBRARY

Title

Real Time Clock running from ISR on TMR0

Author

Eur van Andel, Copyright (c) 2003..2008, all rights reserved., Adapted-by: Rob Hamerling

Compiler

2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This Interrupt Service Routine updates the variable seconds
about once per second. The precision is 0.2 ppm, the accuracy depends
on the Xtal used.

Notes

This is the Bresenham Line Algorithm, invented at IBM in 1962,
which gets an accurate end result by summing the small errors resulting of
taking discrete steps and correcting when the error gets too large. This
means that individual second lengths may show some jitter, but that long-term
timekeeping is accurate. Original assembler by Roman Black.
.
At 20 MHz, so 200ns/clock, so 5 000 000 clocks/second
Rhe RTC has three bytes: bres_hi, bres_mid, bres_lo
timer 0 runs on internal clock speed and interrupts on overflow
every timer 0 interrupt decreases bres_mid by one.
The 5 000 000 value is added when bres_hi en bres_mid are zero
note that remainder is added to bres_lo, which can overflow in bres_mid
this keeps clock count accurate, although interrupts happen every 256 clock
counts the ISR subtracts 1 from the mid byte. It first checks
the mid byte for zero and borrows a bit from bres_hi if needed.
.
Required PIC settings: T0CON_PSA = 1
T0CON_PS = 0
T0CON_T0CS = 0 -- Timer0 on instruction cycle clock

Sources

http://www.romanblack.com/one_sec.htm
http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Routines

  • RTC - Procedure


rtc_isr_tmr1.jal - JALLIB Library Documentation

rtc_isr_tmr1.jal JALLIB LIBRARY

Title

Real Time Clock running from ISR on TMR2

Author

Eur van Andel, Copyright (c) 2010, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This Interrupt Service Routine updates the variable seconds
about once per second. The precision is 0.2 ppm, the accuracy depends
on the Xtal used. The main program should check if seconds are > 60 and
if so, increase minutes, hours, days, months, etc. calendar.jal does this

Notes

This is the Bresenham Line Algorithm, invented at IBM in 1962,
which gets an accurate end result by summing the small errors resulting of
taking discrete steps and correcting when the error gets too large. This
means that individual second lengths may show some jitter, but that long-term
timekeeping is accurate.
.
For instance: if xtal=20 MHz, then 5 MHz clock, so 5 000 000 clocks/second
TMR2 runs on internal clock speed and interrupts on overflow
every TMR2 interrupt decreases _rtc_bresenham by 0x1_00_00, or 2^16
if _rts_bresenham < 0x1_00_00 then 5_000_000 is added
so the jitter is 2^15/5e6 = 0.6%
Total second count is accurate, since the lower 15 bits stay intact and add up
.
This RTC runs on TMR1. You must setup TMR1 yourself
an example how to do this for a PIC16F876A is given here:
prescaler = 1, internal clock, TMR1 = on
PIE1_TMR1IE = on, INTCON_PEIE = on, INTCON_GIE = on
.
T1CON_T1CKPS = 0b00 -- 1:1 prescaler
T1CON_T1OSCEN = off
T1CON_TMR1CS = off
T1CON_TMR1ON = on -- TMR1 on
.
PIE1_TMR1IE = on -- TMR2 interrupt enabled
INTCON_PEIE = on -- peripheral interrupt enabled
INTCON_GIE = on -- global interrupt enabled

Sources

http://www.romanblack.com/one_sec.htm
http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Routines

  • RTC - Procedure


rtc_isr_tmr2.jal - JALLIB Library Documentation

rtc_isr_tmr2.jal JALLIB LIBRARY

Title

Real Time Clock running from ISR on TMR2

Author

Eur van Andel, Copyright (c) 2010, all rights reserved.

Compiler

2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This Interrupt Service Routine updates the variable seconds
about once per second. The precision is 0.2 ppm, the accuracy depends
on the Xtal used. The main program should check if seconds are > 60 and
if so, increase minutes, hours, days, months, etc. calendar.jal does this

Notes

This is the Bresenham Line Algorithm, invented at IBM in 1962,
which gets an accurate end result by summing the small errors resulting of
taking discrete steps and correcting when the error gets too large. This
means that individual second lengths may show some jitter, but that long-term
timekeeping is accurate.
.
For instance: if xtal=20 MHz, then 5 MHz clock, so 5 000 000 clocks/second
TMR2 runs on internal clock speed and interrupts on overflow
every TMR2 interrupt decreases _rtc_bresenham by 0x1_00_00, or 2^16
if _rts_bresenham < 0x1_00_00 then 5_000_000 is added
so the jitter is 2^15/5e6 = 0.6%
Total second count is accurate, since the lower 15 bits stay intact and add up
.
This RTC runs on TMR2. You must setup TMR2 yourself
an example how to do this for a PIC16F876A is given here:
prescaler = 1, internal clock, TMR2 = on
PIE_TMR2IE = on, INTCON_GIE = on
.
T2CON_TOUTPS = 0b0000 -- 1:1 postscaler
T2CON_TMR2_ON = on -- TMR2 on
T2CON_T2CKPS = 0b00 -- 1:1 prescaler
.
PIE_TMR2IE = on -- TMR2 interrupt enabled
INTCON_PEIE = on -- peripheral interrupt enabled
INTCON_GIE = on -- global interrupt enabled

Sources

http://www.romanblack.com/one_sec.htm
http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Routines

  • RTC - Procedure


rtc_isr_tmr3.jal - JALLIB Library Documentation

rtc_isr_tmr3.jal JALLIB LIBRARY

Title

Real Time Clock running from ISR on TMR3

Author

Eur van Andel, Copyright (c) 2010, all rights reserved.

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This Interrupt Service Routine updates the variable seconds
about once per second. The precision is 0.2 ppm, the accuracy depends
on the Xtal used. The main program should check if seconds are > 60 and
if so, increase minutes, hours, days, months, etc. calendar.jal does this

Notes

This is the Bresenham Line Algorithm, invented at IBM in 1962,
which gets an accurate end result by summing the small errors resulting of
taking discrete steps and correcting when the error gets too large. This
means that individual second lengths may show some jitter, but that long-term
timekeeping is accurate.
.
For instance: if xtal=20 MHz, then 5 MHz clock, so 5 000 000 clocks/second
TMR3 runs on internal clock speed and interrupts on overflow
every TMR3 interrupt decreases _rtc_bresenham by 0x1_00_00, or 2^16
if _rts_bresenham < 0x1_00_00 then 5_000_000 is added
so the jitter is 2^15/5e6 = 0.6%
Total second count is accurate, since the lower 15 bits stay intact and add up
.
Example of use:
init_timer3 () ;initialize TMR3
INTCON_GIE = on ;enable interrupts
PIE2_TMR3IE = on ;enable TMR3 interrupts
forever loop
; use seconds for whatever you need
end loop

Sources

http://www.romanblack.com/one_sec.htm
http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm

Routines

  • RTC - Procedure
  • init_timer3 - Procedure


rtc_mcp7940.jal - JALLIB Library Documentation

rtc_mcp7940.jal JALLIB LIBRARY

Title

Real time clock MCP7940

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides functions for I2C real time clock mcp7940.
A nice small RTC with a backup power supply pin to keep time
during power outage. 64bytes sram is also kept during power
outage.

Notes

Works, but not complete. Still need to add procedures to set time
and calabrate.

Sources

----------------------------------------------------------------------------

harware identification:

Routines

  • rtc_day_of_month'get - Function returns byte
  • rtc_hour'get - Function returns byte
  • rtc_mcp7940_init - Procedure
  • rtc_mcp7940_read - Function returns byte
  • rtc_mcp7940_select_supply_voltage - Procedure
  • rtc_mcp7940_write - Procedure
  • rtc_mem'get - Function returns byte
  • rtc_mem'put - Procedure
  • rtc_minute'get - Function returns byte
  • rtc_month'get - Function returns byte
  • rtc_second'get - Function returns byte
  • rtc_week_day'get - Function returns byte
  • rtc_year'get - Function returns word


rtc_mcp7940_init - JALlib Procedures Help

rtc_mcp7940_init JALLIB PROCEDURE

Signature

procedure rtc_mcp7940_init() is

Description

Init mcp7940 (start it's clock)

Include

To use this procedure, include the library:

include rtc_mcp7940

Parameters

None

Return Value

None

Example

From sample file: 18f4620_rtc_mcp7940.jal

-- Title: Real time clock MCP7940
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads time from I2C real time clock mcp7940.
--              A nice small RTC with a backup power supply pin to keep time
--              during power outage. 64bytes sram is also kept during power
--              outage.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: Works, but not complete. Still need to add procedures to set time
--        and calabrate.
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT  -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup i2c software
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl            is pin_scl
alias i2c_scl_direction  is pin_scl_direction
alias i2c_sda            is pin_sda
alias i2c_sda_direction  is pin_sda_direction
--
include i2c_software
i2c_initialize()

-- setup RTC MCP7940
include rtc_mcp7940
rtc_mcp7940_init()                  -- init rtc_mcp7940
--
rtc_mcp7940_select_supply_voltage() -- use normal supply, not vbat.

const byte hello_world[] = "HELLO WORLD!"
print_string(serial_data, hello_world)
print_crlf(serial_data)
print_crlf(serial_data)

--
-- Specify the pin to which the LED (with serial resistor!) is connected:
alias   led      is pin_A0
pin_A0_direction =  output
--

-- read/write sram memory.
-- sram is kept by backup supply during main power failure.
rtc_mem[0] = 0xAA
print_byte_hex(serial_data, rtc_mem[0])
print_crlf(serial_data)

var byte time_check
forever loop

   -- wait for next second
   ;time_check = rtc_read_second()
   ;while time_check == rtc_read_second() loop
   ;end loop

   const byte date[] = "YYYY/MM/DD: "
   print_string(serial_data, date)

   print_word_dec(serial_hw_data,rtc_year)
   serial_data = "/"
   if rtc_month < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_month)
   serial_data = "/"
   if rtc_day_of_month < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_day_of_month)
   print_crlf(serial_data)

   const byte week_day[] = "Week Day: "
   print_string(serial_data, week_day)
   print_byte_dec(serial_hw_data,rtc_week_day)
   print_crlf(serial_data)

   -- print "Time: "
   const byte time[] = "Time: "
   print_string(serial_data, time)

   -- print the hour
   print_byte_dec(serial_hw_data,rtc_hour)

   -- print the minute
   serial_data = ":"
   if rtc_minute < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_minute)

   -- print the second
   serial_data = ":"
   if rtc_second < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_second)
   print_crlf(serial_data)

   const byte seperator[] = "----------------------"
   print_string(serial_data, seperator)
   print_crlf(serial_data)
   _usec_delay(1_000_000)
end loop

--

Generated by JALlib CHM Help System | Source: rtc_mcp7940.jal


rtc_mcp7940_select_supply_voltage - JALlib Procedures Help

rtc_mcp7940_select_supply_voltage JALLIB PROCEDURE

Signature

procedure rtc_mcp7940_select_supply_voltage() is

Description

Use supply voltage, not VBAT battery backup. This must be used after any
power outage. Using this procedure will clear the time stamp registers (the
time the outage occurred).

Include

To use this procedure, include the library:

include rtc_mcp7940

Parameters

None

Return Value

None

Example

From sample file: 18f4620_rtc_mcp7940.jal

-- Title: Real time clock MCP7940
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads time from I2C real time clock mcp7940.
--              A nice small RTC with a backup power supply pin to keep time
--              during power outage. 64bytes sram is also kept during power
--              outage.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: Works, but not complete. Still need to add procedures to set time
--        and calabrate.
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT  -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup i2c software
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl            is pin_scl
alias i2c_scl_direction  is pin_scl_direction
alias i2c_sda            is pin_sda
alias i2c_sda_direction  is pin_sda_direction
--
include i2c_software
i2c_initialize()

-- setup RTC MCP7940
include rtc_mcp7940
rtc_mcp7940_init()                  -- init rtc_mcp7940
--
rtc_mcp7940_select_supply_voltage() -- use normal supply, not vbat.

const byte hello_world[] = "HELLO WORLD!"
print_string(serial_data, hello_world)
print_crlf(serial_data)
print_crlf(serial_data)

--
-- Specify the pin to which the LED (with serial resistor!) is connected:
alias   led      is pin_A0
pin_A0_direction =  output
--

-- read/write sram memory.
-- sram is kept by backup supply during main power failure.
rtc_mem[0] = 0xAA
print_byte_hex(serial_data, rtc_mem[0])
print_crlf(serial_data)

var byte time_check
forever loop

   -- wait for next second
   ;time_check = rtc_read_second()
   ;while time_check == rtc_read_second() loop
   ;end loop

   const byte date[] = "YYYY/MM/DD: "
   print_string(serial_data, date)

   print_word_dec(serial_hw_data,rtc_year)
   serial_data = "/"
   if rtc_month < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_month)
   serial_data = "/"
   if rtc_day_of_month < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_day_of_month)
   print_crlf(serial_data)

   const byte week_day[] = "Week Day: "
   print_string(serial_data, week_day)
   print_byte_dec(serial_hw_data,rtc_week_day)
   print_crlf(serial_data)

   -- print "Time: "
   const byte time[] = "Time: "
   print_string(serial_data, time)

   -- print the hour
   print_byte_dec(serial_hw_data,rtc_hour)

   -- print the minute
   serial_data = ":"
   if rtc_minute < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_minute)

   -- print the second
   serial_data = ":"
   if rtc_second < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_second)
   print_crlf(serial_data)

   const byte seperator[] = "----------------------"
   print_string(serial_data, seperator)
   print_crlf(serial_data)
   _usec_delay(1_000_000)
end loop

--

Generated by JALlib CHM Help System | Source: rtc_mcp7940.jal


rtc_pcf8563.jal - JALLIB Library Documentation

rtc_pcf8563.jal JALLIB LIBRARY

Title

Programme to read and control PCF8563 real time IC

Author

Andy Brooker, Copyright (c) 2008..2011, all rights reserved., Adapted-by: (Joep Suijs)

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Programme to read and control the PCF8563 real time IC
IC address is 0xA2
PCF8563 read sequence
1. Send a START condition and the slave address for write (A2h).
2. Set the address pointer to 2 (VL_seconds) by sending 02h.
3. Send a RESTART condition or STOP followed by START.
4. Send the slave address for read (A3h).
5. Read VL_seconds. 02
6. Read Minutes. 03
7. Read Hours. 04
8. Read Days. 05
9. Read Weekdays. 06
10. Read Century_months. 07
11. Read Years. 08
12. Send a STOP condition.
--
To use set:
-- const byte pcf8563_address = 0xA2
-- include rtc_pcf8563

Sources

procedure to write a register - send data as decimal

Constants and Variables

r - var bit

Routines

  • pcf8563_register_write - Procedure
  • read_pcf8563 - Procedure


rtc_pin_signal - JALlib Procedures Help

rtc_pin_signal JALLIB PROCEDURE

Signature

procedure rtc_pin_signal(bit*2 in pin_signal_selection_mask) is

Description

No description available.

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • pin_signal_selection_mask - bit*2 in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_read_dayofweek - JALlib Procedures Help

rtc_read_dayofweek JALLIB FUNCTION

Signature

function rtc_read_dayofweek() return byte is

Description

Read day of week value from rtc.
Note: In rct_common.jal this is calculated using rtc_calc_dayofweek()

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_read_full_year - JALlib Procedures Help

rtc_read_full_year JALLIB FUNCTION

Signature

function rtc_read_full_year() return word is

Description

Read the full year value from rtc in bcd notation. The high byte of the
return value contains the year hunderds in bcd, the low byte the tens years
in bcd.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_read_reg_ - JALlib Procedures Help

rtc_read_reg_ JALLIB PROCEDURE

Signature

procedure rtc_read_reg_(byte in register, byte out data) is

Description

Read specified data from a specified register

Include

To use this procedure, include the library:

include rtc_ds1302

Parameters

  • register - byte in
  • data - byte out

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds1302.jal


rtc_read_second - JALlib Procedures Help

rtc_read_second JALLIB FUNCTION

Signature

function rtc_read_second() return byte is

Description

Read second value from rtc in bcd notation.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 18f4620_rtc_mcp7940.jal

-- Title: Real time clock MCP7940
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample reads time from I2C real time clock mcp7940.
--              A nice small RTC with a backup power supply pin to keep time
--              during power outage. 64bytes sram is also kept during power
--              outage.
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: Works, but not complete. Still need to add procedures to set time
--        and calabrate.
--

-- include chip
include 18f4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT  -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup i2c software
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true   ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl            is pin_scl
alias i2c_scl_direction  is pin_scl_direction
alias i2c_sda            is pin_sda
alias i2c_sda_direction  is pin_sda_direction
--
include i2c_software
i2c_initialize()

-- setup RTC MCP7940
include rtc_mcp7940
rtc_mcp7940_init()                  -- init rtc_mcp7940
--
rtc_mcp7940_select_supply_voltage() -- use normal supply, not vbat.

const byte hello_world[] = "HELLO WORLD!"
print_string(serial_data, hello_world)
print_crlf(serial_data)
print_crlf(serial_data)

--
-- Specify the pin to which the LED (with serial resistor!) is connected:
alias   led      is pin_A0
pin_A0_direction =  output
--

-- read/write sram memory.
-- sram is kept by backup supply during main power failure.
rtc_mem[0] = 0xAA
print_byte_hex(serial_data, rtc_mem[0])
print_crlf(serial_data)

var byte time_check
forever loop

   -- wait for next second
   ;time_check = rtc_read_second()
   ;while time_check == rtc_read_second() loop
   ;end loop

   const byte date[] = "YYYY/MM/DD: "
   print_string(serial_data, date)

   print_word_dec(serial_hw_data,rtc_year)
   serial_data = "/"
   if rtc_month < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_month)
   serial_data = "/"
   if rtc_day_of_month < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_day_of_month)
   print_crlf(serial_data)

   const byte week_day[] = "Week Day: "
   print_string(serial_data, week_day)
   print_byte_dec(serial_hw_data,rtc_week_day)
   print_crlf(serial_data)

   -- print "Time: "
   const byte time[] = "Time: "
   print_string(serial_data, time)

   -- print the hour
   print_byte_dec(serial_hw_data,rtc_hour)

   -- print the minute
   serial_data = ":"
   if rtc_minute < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_minute)

   -- print the second
   serial_data = ":"
   if rtc_second < 10 then
   serial_data = "0"
   end if
   print_byte_dec(serial_hw_data,rtc_second)
   print_crlf(serial_data)

   const byte seperator[] = "----------------------"
   print_string(serial_data, seperator)
   print_crlf(serial_data)
   _usec_delay(1_000_000)
end loop

--

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_set_alarm - JALlib Procedures Help

rtc_set_alarm JALLIB PROCEDURE

Signature

procedure rtc_set_alarm(bit in state) is

Description

Enable or disable alarm
input: alarm_state (bit): true - enable alarm
false - disable alarm
output: none
returns: (nothing)

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • state - bit in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_set_alarm_1_rate - JALlib Procedures Help

rtc_set_alarm_1_rate JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_1_rate(byte in rate) is

Description

Set alarm 1 rate according to the given parameter.
Note: When using RTC_ALARM_1_DATE_HOUR_MIN_SEC_MATCH or
RTC_ALARM_1_DAY_HOUR_MIN_SEC_MATCH make sure to have set the
alarm date or alarm day accordingly.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • rate - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_set_alarm_1_time_bin - JALlib Procedures Help

rtc_set_alarm_1_time_bin JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_1_time_bin(byte in hour, byte in minutes, byte in seconds) is

Description

Set alarm 1 time in hours, minutes and seconds in binary notation.
Hours must be in 24-hours format.
When the alarm time matches then rtc_alarm_1_flag will be set and must be
cleared by the user.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • hour - byte in
  • minutes - byte in
  • seconds - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_set_alarm_2_rate - JALlib Procedures Help

rtc_set_alarm_2_rate JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_2_rate(byte in rate) is

Description

Set alarm 2 rate according to the given parameter.
Note: When using RTC_ALARM_2_DATE_HOUR_MIN_MATCH or
RTC_ALARM_2_DAY_HOUR_MIN_MATCH make sure to have set the
alarm date or alarm day accordingly.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • rate - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_set_alarm_2_time_bin - JALlib Procedures Help

rtc_set_alarm_2_time_bin JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_2_time_bin(byte in hour, byte in minutes) is

Description

Set alarm 2 time in hours and minutes in binary notation.
Hours must be in 24-hours format.
When the alarm time matches then rtc_alarm_2_flag will be set and must be
cleared by the user.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • hour - byte in
  • minutes - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_set_alarm_interval - JALlib Procedures Help

rtc_set_alarm_interval JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_interval(byte in interval) is

Description

No description available.

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • interval - byte in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_set_alarm_repeat - JALlib Procedures Help

rtc_set_alarm_repeat JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_repeat(byte in repeats) is

Description

Set alarm repetition.
input: repeats: number of times to repeat alarm signal (binary)
output: none
returns: (nothing)
notes: The following will happen after an alarm condition:
- with repeat value 0 there will be 1 alarm event
- with repeat values 1..254 there will be as many more alarm
events as specified with
(at intervals specified with rtc_set_alarm_interval() )
- with repeat value 255 there will be indefinite alarm events
The ALRMCFG_ALRMEN bit will be cleared after the last alarm event
(thus never with repeat value 255).

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • repeats - byte in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_set_alarm_time_bcd - JALlib Procedures Help

rtc_set_alarm_time_bcd JALLIB PROCEDURE

Signature

procedure rtc_set_alarm_time_bcd(byte in hh, byte in mm, byte in ss) is

Description

Write alarm time
input: alarm hour, minute, second (bcd format)
output: none
returns: (nothing)
notes: - disable alarm, modify alarm registers, restore alarm

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • hh - byte in
  • mm - byte in
  • ss - byte in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_set_clock - JALlib Procedures Help

rtc_set_clock JALLIB PROCEDURE

Signature

procedure rtc_set_clock(bit in state) is

Description

Enable or disable the RTCC module.
input: none
output: none
returns: nothing
notes: The T1 oscillator is enable/disabled too!

Include

To use this procedure, include the library:

include rtcc_hw

Parameters

  • state - bit in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtcc_hw.jal


rtc_set_date_bcd - JALlib Procedures Help

rtc_set_date_bcd JALLIB PROCEDURE

Signature

procedure rtc_set_date_bcd(byte in yy, byte in mm, byte in dd) is

Description

Title: set date (year, month, dayofmonth) in bcd notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • yy - byte in
  • mm - byte in
  • dd - byte in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_set_date_bin - JALlib Procedures Help

rtc_set_date_bin JALLIB PROCEDURE

Signature

procedure rtc_set_date_bin(byte in yy, byte in mm, byte in dd) is

Description

Title: set date (year, month, dayofmonth) in binary notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • yy - byte in
  • mm - byte in
  • dd - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_set_square_wave - JALlib Procedures Help

rtc_set_square_wave JALLIB PROCEDURE

Signature

procedure rtc_set_square_wave(byte in frequency) is

Description

Set the square wave frequency and output.
Note: This will disable the interrupt functionality on the INT/SQW pin.
The M version of the DS3231 can only generate the 1 Hz signal.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • frequency - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_set_time_bcd - JALlib Procedures Help

rtc_set_time_bcd JALLIB PROCEDURE

Signature

procedure rtc_set_time_bcd(byte in hh, byte in mm, byte in ss) is

Description

Title: set time (hour, minute, second) in bcd notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • hh - byte in
  • mm - byte in
  • ss - byte in

Return Value

None

Example

From sample file: 18f26j11_rtcc_hw_kbd_lcd.jal

-- =====================================================================
-- Title: Alarm clock using the RTCC module of PIC and rtc_hardware library.
--
-- Author: Rob Hamerling, Copyright (c) 2010..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description:
-- Alarm clock program using the RTCC module of the 18f26j11
-- (or of any other PIC with compatible RTCC module).
-- Date, time, alarm-time and other settings are displayed on 4x20 LCD display
-- and can be controlled with a numeric 3x4 keyboard via a simple menu system:
--  *  key is for entering menu selection (when repeated: next menu item)
--     Functions also as backspace during keying of a new value!
--  0..9 keys determine the new value.
--  #  key is end of operation (accept new value, return to normal operation).
--  All keys except '*' are ignored when not in a menu.
--  The oscillator calibration value has the range -128..+127, Since the
--  keyboard has no '- and '+' keys only an unsigned number 0..255 can be
--  entered. A value x above 127 is interpreted as (x - 256).
--  For example: 200 is interpreted as -56 (and shown as such).
-- .
-- Only some simple error checking is implemented.
-- Out of range key entries are refused (ignored).
--
-- Sources:
--
-- Notes:
--
-- =====================================================================
--
include  18f26j11                                  -- target chip

-- Internal oscillator is configured for 8 MHz

pragma target clock         8_000_000              -- intocs 8 MHz

-- configuration bits

pragma target WDT           CONTROL                -- watchdog software controlled!
pragma target STVR          DISABLED               -- reset on stack over/under flow
pragma target XINST         DISABLED               -- extended instruction set
pragma target DEBUG         DISABLED               -- background debugging
pragma target CP0           DISABLED               -- code block 0 not protected
pragma target OSC           INTOSC_NOCLKOUT        -- oscillator type
pragma target T1DIG         ENABLED                -- timer1 oscillator
pragma target LPT1OSC       LOW_POWER              -- low power timer 1
pragma target FCMEN         DISABLED               -- fail safe clock monitor
pragma target IESO          DISABLED               -- osc switch over
pragma target WDTPS         P64                    -- watchdog timeout 256 msec
pragma target DSWDTOSC      T1                     -- for deep sleep WDT
pragma target RTCOSC        T1OSC                  -- 32768 Hz crystal at T1OSI/T1OSO
pragma target BROWNOUT      DISABLED               -- no brownout detection
pragma target DSWDTEN       DISABLED               -- no deep sleep WDT
pragma target DSWDTPS       P2                     -- (no deep sleep WDT)
pragma target IOL1WAY       DISABLED               -- no I/O lock
pragma target MSSPMASK      B5                     -- (no ext ram)
pragma target WPFP          P0                     -- start of code protection
pragma target WPEND         PWPFP_END              -- code protection from ... to end
pragma target WPCFG         DISABLED               -- no code protection!
pragma target WPDIS         DISABLED               -- no write protection

OSCCON_IRCF   = 0b111                              -- 8 MHz
OSCCON_SCS    = 0                                  -- primary clock

-- ------- pin assignments -----------------------------------

--    pin_A0               LDR (not yet used)
--    pin_A1               )
--    pin_A2               ) LCD_data
--    pin_A3               )
--    ------                   (Vcap)
--    pin_A5               )
--    pin_A6               LCD_rs
--    pin_A7               LCD-en

--    pin_B0               kbd  col1
--    pin_B1               RTCC output
--    pin_B2               kbd  col2
--    pin_B3               kbd  col3
--    pin_B4               kbd  row 1
--    pin_B5               kbd  row 2
--    pin_B6               kbd  row 3
--    pin_B7               kbd  row 4

--    pin_C0               T1OSO
--    pin_C1               T1OSI
--    pin_C2               group 1
--    pin_C3               group 2
--    pin_C4               on  a
--    pin_C5               off a
--    pin_C6               on  b
--    pin_C7               off b

-- ------ keyboard interface -------------------------

alias    keydrive           is  portB_low
alias    keydrive_direction is  portB_low_direction
alias    keyscan            is  portB_high
alias    keyscan_direction  is  portB_high_direction

const    byte    ROW1       = 0b0000_0001
const    byte    ROW2       = 0b0000_0010
const    byte    ROW3       = 0b0000_0100
const    byte    ROW4       = 0b0000_1000
const    byte    COL1       = 0b0000_0001
const    byte    COL2       = 0b0000_0100
const    byte    COL3       = 0b0000_1000
const    byte    COL4       = 0b0000_0000       -- (no fourth column)

include  keyboard                               -- keyboard support library

-- ------ LCD interface -----------------------------------

const    byte    LCD_ROWS   = 4                 -- for rows of
const    byte    LCD_CHARS  = 20                -- 20 characters

alias    lcd_d4  is  pin_A5                     -- )
alias    lcd_d5  is  pin_A3                     -- )
alias    lcd_d6  is  pin_A2                     -- ) 4 data lines
alias    lcd_d7  is  pin_A1                     -- )

alias    lcd_rs  is  pin_A6                     -- )
alias    lcd_en  is  pin_A7                     -- ) 2 control lines

include  lcd_hd44780_4                          -- 4 bits LCD support library

-- ------ data formatting ---------------------------------

include  print                                  -- data conversion

-- ------ real time clock interface -----------------------

include  rtcc_hw                                -- RTCC support library

-- --- local function and procedure prototypes ------------

procedure  keyboard_handling(byte in key)       -- handle keyboard activity

-- -------------------------------------------------------

const  byte    KBD_IDLE           = 0         -- valid values of kbd_state
const  byte    KBD_ALARM_ONOFF    = 1
const  byte    KBD_TIME           = 2
const  byte    KBD_DATE           = 3
const  byte    KBD_ALARM_TIME     = 4
const  byte    KBD_ALARM_INTERVAL = 5
const  byte    KBD_ALARM_REPEAT   = 6
const  byte    KBD_CALIBRATE      = 7

const  byte    PROGRAM_TITLE[]    = "RTCC_HW_KBD_LCD   "    -- sample title
const  byte    DAY_OF_WEEK[]      = "SuMoTuWeThFrSa"        -- weekday abbreviations
const  byte    ALARM_INTERVAL_STR[] = "1/2sec10smin10mhr daywk monyr "   -- interval abbr.
const  byte    ALARM_SIGN         = 0b0101_1100             -- Yen(?)

const  byte    TEXT_ALARM[]       = "Alarm "                --
const  byte    TEXT_TIME[]        = "Time "                 --
const  byte    TEXT_DATE[]        = "Date [20]"             --
const  byte    TEXT_ALARM_TIME[]  = "A-Time "               --
const  byte    TEXT_INTERVAL[]    = "Interval "             --
const  byte    TEXT_REPEAT[]      = "Repeat "               --
const  byte    TEXT_CALIBRATE[]   = "Calibrate "            --

var    byte    kbd_state          = KBD_IDLE                -- initial keyboard state
var    byte    kbd_count          = 0                       -- key ('offset') counter

-- -------------------------------------------------------
--  Show one byte in bcd notation as two decimal digits.
--  Simple alternative for print_byte_hex() in the print library
--  (without check or correction of valid bcd notation).
-- -------------------------------------------------------
procedure  show_byte_bcd(volatile byte out device, byte in data) is
   device = "0" + (data >> 4)                   -- high order nibble
   device = "0" + (data & 0x0F)                 -- low order nibble
end procedure

-- -------------------------------------------------------
--  Show array of 3 bytes in bcd notation
-- -------------------------------------------------------
procedure  show_3byte_bcd(volatile byte out device,
                          byte  in data[3],
                          byte  in separator) is
   show_byte_bcd(device, data[0])
   device = separator
   show_byte_bcd(device, data[1])
   device = separator
   show_byte_bcd(device, data[2])
end procedure

-- -------------------------------------------------------
--  Globally initialize PIC, specific init details in mainline
-- -------------------------------------------------------
procedure  setup_pic() is
   INTCON        = 0b0000_0000                  -- no interrupts
   portA         = 0b0000_0000                  -- init portA
   portB         = 0b0000_0000                  -- init portB
   portC         = 0b0000_0000                  -- init portC
   T1CON         = 0b0000_0000                  -- Tmr1 off
   T1CON_T1OSCEN = TRUE                         -- Tmr1 oscillator enabled
   T2CON         = 0b0000_0000                  -- Tmr2 off
   portA_direction = all_output                 --
   portB_direction = all_output                 -- all ports initially output
   portC_direction = all_output                 --
   OSCCON_IDLEN  = 0                            -- for sleep (not idle) mode
   REFOCON_ROON  = FALSE                        -- no oscillator output
   WDTCON        = 0b0000_0000                  -- all bits off
   WDTCON_REGSLP = 1                            -- voltage regulator off in sleep
   WDTCON_SWDTEN = 1                            -- enable wdt
   DSCONH_DSEN   = 1                            -- 0=normal, 1=deep sleep mode

end procedure

-- ===============================================================
--
--   M A I N L I N E
--
-- ===============================================================

enable_digital_io()                             -- disable all analog I/O

setup_pic()                                     -- globally init PIC

keyscan_direction = all_input                   -- keyboard scan
keydrive_direction = all_output                 -- keyboard drive

lcd_init()                                      -- initialize LCD display

rtc_set_clock(ENABLED)                          -- enable RTCC module
rtc_calibrate(15)                               -- initial calibration value

-- dates and times are stored as 3-byte arrays with
-- sequence year-month-date resp. hour-minute-second sequence.

var  byte    date[3]      = { 0x15,0x05,0x19 }  -- actual date
var  byte    time[3]      = { 0x19,0x29,0x55 }  -- actual time
var  byte    weekday                            -- day of week
var  byte    alarmtime[3] = { 0x07,0x30,0x10 }  -- actual alarmtime: 07:30:10
var  bit     alarm_onoff  = ON                  -- alarm, init: on
var  byte    alarm_interval = RTC_ALARM_INTERVAL_HALFSECOND  -- init: 1/2 sec
var  byte    alarm_repeat = 0                   -- alarm-repeat, init: 0
var  byte    calibrate                          -- OSC calibration value

var  byte    newdate[3]                         -- new date (yymmdd bcd format)
var  byte    newtime[3]                         -- new time (hhmmss bcd format)
var  byte    newalarmtime[3]                    -- new alarm time (hhmmss bcd format)
var  byte    nalarm_interval                    -- new alarm-interval
var  byte    nalarm_repeat                      -- new alarm-repeat
var  byte    ncalibrate                         -- new calibrate value

var  byte    key                                -- keyboard key value

rtc_set_date_bcd(date[0], date[1], date[2])                       -- )
rtc_set_time_bcd(time[0], time[1], time[2])                       -- ) initial values
rtc_set_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])  -- )

rtc_pin_signal(RTC_PIN_ALARM)                   -- pin_RTCC function

forever loop

   -- handle realtime clock

   weekday = rtc_dayofweek
   lcd_cursor_position(0,0)                     -- first line
   lcd = DAY_OF_WEEK[2 * (weekday - 1)]         -- day of week
   lcd = DAY_OF_WEEK[2 * (weekday - 1) + 1]     -- day of week
   lcd = " "                                    -- separator
   lcd = "2"                                    -- ) 21st century only
   lcd = "0"                                    -- )
   rtc_get_date_bcd(date[0], date[1], date[2])  -- current date
   show_3byte_bcd(lcd, date, "/")

   lcd = " "                                    -- ) for debugging
   print_sbyte_dec(lcd, sbyte(RTCCAL))          -- ) only
   lcd = " "
   lcd = " "
   lcd = " "

   lcd_cursor_position(0,LCD_CHARS - 1)         -- top right corner
   if (alarm_onoff == ON) then
      lcd = ALARM_SIGN                          -- show alarm 'ON'
   else
      lcd = " "                                 -- clear alarm sign
   end if

   lcd_cursor_position(1,0)                     -- second line
   lcd_clear_line(1)                            -- clear it
   rtc_get_time_bcd(time[0], time[1], time[2])
   show_3byte_bcd(lcd, time, ":")               -- current time
   lcd_cursor_position(1,10)
   print_dword_dec(lcd,rtc_secondofday)   -- )
   lcd_cursor_position(1,16)
   print_word_dec(lcd,rtc_minuteofday)    -- )

   lcd_cursor_position(2,0)                     -- third line
   rtc_get_alarm_time_bcd(alarmtime[0], alarmtime[1], alarmtime[2])
   show_3byte_bcd(lcd, alarmtime, ":")          -- current alarm time
   lcd_cursor_position(2,9)                     -- position
   lcd = "I"                                    -- 'Interval'
   lcd = "="
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 1]
   lcd = ALARM_INTERVAL_STR[alarm_interval * 3 + 2]
   lcd_cursor_position(2,15)                    -- position
   lcd = "R"                                    -- 'Repeat count'
   lcd = "="                                    -- separator
   lcd_cursor_position(2,17)                    -- position
   print_byte_dec(lcd,alarm_repeat)             -- current alarm interval
   if (alarm_repeat < 10) then                  -- 1 digit number
      lcd = " "                                 -- separator
   end if
   if (alarm_repeat < 100) then                 -- 2 digit number
      lcd = " "                                 -- separator
   end if

   -- bottom line: display pending change or a fixed text string.

   lcd_cursor_position(LCD_ROWS - 1,0)          -- lower left corner

   case kbd_state of

      KBD_IDLE:
         block
            print_string(lcd, PROGRAM_TITLE)    -- program title
         end block

      KBD_ALARM_ONOFF:
         block
            print_string(lcd, TEXT_ALARM)       -- alarm text
            lcd = "O"
            if (alarm_onoff == ON) then
               lcd = "n"                        -- alarm on
               lcd = " "
            else
               lcd = "f"                        -- alarm off
               lcd = "f"
            end if
         end block

      KBD_TIME:
         block
            print_string(lcd, TEXT_TIME)        -- time text
            show_3byte_bcd(lcd,newtime,":")
         end block

      KBD_DATE:
         block
            print_string(lcd, TEXT_DATE)        -- date text
            show_3byte_bcd(lcd,newdate,"/")
         end block

      KBD_ALARM_TIME:
         block
            print_string(lcd, TEXT_ALARM_TIME)  -- interval text
            show_3byte_bcd(lcd,newalarmtime,":")
         end block

      KBD_ALARM_INTERVAL:
         block
            print_string(lcd, TEXT_INTERVAL)    -- interval text
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3]     -- interval value
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 1]
            lcd = ALARM_INTERVAL_STR[nalarm_interval * 3 + 2]
         end block

      KBD_ALARM_REPEAT:
         block
            print_string(lcd, TEXT_REPEAT)      -- repeat text
            print_byte_dec(lcd,nalarm_repeat)   -- current repeat value
            lcd = " "
            lcd = " "
         end block

      KBD_CALIBRATE:
         block
            print_string(lcd, TEXT_CALIBRATE)   -- calibrate text
            print_sbyte_dec(lcd,sbyte(ncalibrate)) -- calibration value
         end block

   end case

   -- handle keyboard activity if any

   key = getkey_once()                          -- determine key pressed

   lcd_cursor_position(LCD_ROWS-1,LCD_CHARS-2)  -- lower right
   print_byte_hex(lcd, key)                     -- debug

   if (key < 16) then                           -- valid key
      keyboard_handling(key)                    -- specific key handling
   end if

   if (kbd_state == KBD_IDLE) then              -- no pending keyboard activity
      asm sleep                                 -- enter sleep mode
   else
      asm clrwdt                                -- reset watchdog timeout
   end if

end loop

-- -------------------------------------------------------
--  Handle keyboard activity
--  Contains some input validation checking,
--  but does not intercept all faulty input.
-- -------------------------------------------------------
procedure keyboard_handling(byte in key) is

   -- handle new key, based on active menu and previous progress within menu

   case kbd_state of

      KBD_IDLE:                                 -- no keyboard action pending
         block
            if (key == 10) then                 -- asterisk
               kbd_state = KBD_ALARM_ONOFF      -- to alarm status menu
               kbd_count = 0                    -- no change pending
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            end if
         end block

      KBD_ALARM_ONOFF:                          -- switch alarm on/off
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- first key
                  kbd_state = KBD_TIME          -- to Time menu
                  newtime[0] = time[0]          -- init
                  newtime[1] = time[1]
                  newtime[2] = time[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else
                  kbd_count = kbd_count - 1     -- back
               end if
            elsif (key == 11) then              -- 'Enter'
               kbd_state = KBD_IDLE             -- reset state
               kbd_count = 0                    -- done
            else                                -- any other key
               if (alarm_onoff == OFF) then     -- currently off
                  alarm_onoff = ON              -- switch to on
                  rtc_set_alarm(ON)             -- alarm on
                  rtc_pin_signal(RTC_PIN_ALARM) -- alarm on
               else                             -- currently on
                  alarm_onoff = OFF             -- switch to off
                  rtc_set_alarm(OFF)            -- alarm on
                  rtc_pin_signal(RTC_PIN_NONE)  -- alarm on
               end if
               kbd_count = 1                    -- single key input
            end if
         end block

      KBD_TIME:                                 -- time setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no time action pending
                  kbd_state = KBD_DATE          -- to Date menu
                  newdate[0] = date[0]          -- init
                  newdate[1] = date[1]
                  newdate[2] = date[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        newtime[0] = 0
                        newtime[1] = 0
                        newtime[2] = 0
                        if (key <= 2) then
                           newtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newtime[0] < 0x20) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        elsif (key < 4) then
                           newtime[0] = newtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newtime[1] = newtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newtime[2] = newtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_hour_bcd = newtime[0]
                  rtc_minute_bcd = newtime[1]
                  rtc_second_bcd = newtime[2]
 --               rtc_set_time(newtime[0], newtime[1], newtime[2])     -- store new time
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_DATE:                                 -- date setting pending
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no date action pending
                  kbd_state = KBD_ALARM_TIME    -- to alarm time menu
                  newalarmtime[0] = alarmtime[0] -- init
                  newalarmtime[1] = alarmtime[1]
                  newalarmtime[2] = alarmtime[2]
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of                -- selection on previous kbd input
                  0: block                      -- tens of year
                        newdate[0] = key << 4
                        kbd_count = 1
                     end block
                  1: block                      -- units of year
                        newdate[0] = newdate[0] | key
                        kbd_count = 2
                     end block
                  2: block                      -- tens of month
                        if (key == 0  |  key == 1) then
                           newdate[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block                      -- units of month
                        if (newdate[1] == 0x00) then      -- months 1..9
                           if (key > 0) then
                              newdate[1] = key
                              kbd_count = 4
                           end if
                        elsif (key <= 2) then   -- months 10,11,12
                           newdate[1] = newdate[1] | key
                           kbd_count = 4
                        end if
                     end block
                  4: block                      -- tens of day of month
                        if (key < 4) then       -- limit to 31 days
                           newdate[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block                      -- units of day of month
                        if (newdate[2] == 0x00) then      -- days 1..9
                           if (key > 0) then
                              newdate[2] = key
                              kbd_count = 6
                           end if
                        elsif (newdate[2] == 0x10  | newdate[2] == 0x20) then  -- days 10..29
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        elsif (key <= 1) then            -- days 30,31
                           newdate[2] = newdate[2] | key
                           kbd_count = 6
                        end if
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- new time prepared
                  rtc_year_bcd = newdate[0]
                  rtc_month_bcd = newdate[1]
                  rtc_dayofmonth_bcd = newdate[2]
 --               rtc_set_date(newdate[0], newdate[1], newdate[2])  -- store new date
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_TIME:
         block                                  -- alarm setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no alarm action pending
                  kbd_state = KBD_ALARM_INTERVAL  -- to alarm interval menu
                  nalarm_interval = alarm_interval  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm action pending
                  kbd_count = kbd_count - 1     -- 'backspace'
               end if
            elsif (key < 10) then
               case kbd_count of
                  0: block
                        if (key <= 2) then
                           newalarmtime[0] = key << 4
                           kbd_count = 1        -- next key action
                        end if
                     end block
                  1: block
                        if (newalarmtime[0] < 0x20) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = kbd_count + 1
                        elsif (key < 4) then
                           newalarmtime[0] = newalarmtime[0] | key
                           kbd_count = 2
                        end if
                     end block
                  2: block
                        if (key < 6) then
                           newalarmtime[1] = key << 4
                           kbd_count = 3
                        end if
                     end block
                  3: block
                        newalarmtime[1] = newalarmtime[1] | key
                        kbd_count = 4
                     end block
                  4: block
                        if (key < 6) then
                           newalarmtime[2] = key << 4
                           kbd_count = 5
                        end if
                     end block
                  5: block
                        newalarmtime[2] = newalarmtime[2] | key
                        kbd_count = 6
                     end block
                  otherwise                     -- nothing
               end case
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm clock prepared
                  rtc_set_alarm_time_bcd(newalarmtime[0],newalarmtime[1],newalarmtime[2])
                                                -- store new alarmtime
                  rtc_pin_signal(RTC_PIN_ALARM)   -- output: alarm signal
                  rtc_set_alarm_repeat(alarm_repeat)   -- number of 'pulses'
                  rtc_set_alarm(true)           -- activate alarm function
               else
                  rtc_set_alarm(false)          -- disable alarm
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_INTERVAL:                       -- alarm interval
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_ALARM_REPEAT  -- to alarm repeat menu
                  nalarm_repeat = alarm_repeat  -- init
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  kbd_count = 0                 -- 'backspace'
               end if
            elsif (key <= RTC_ALARM_INTERVAL_YEAR) then
                nalarm_interval = key           -- accept new key
                kbd_count = 1                   -- one digit only!
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_interval = nalarm_interval  -- accept new value
                  rtc_set_alarm_interval(alarm_interval)  -- write to rtcc
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_ALARM_REPEAT:                         -- alarm repeat value
         block                                  -- alarm interval setting pending
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- reset progress counter
                  kbd_state = KBD_CALIBRATE     -- to calibration menu
                  ncalibrate = 0                -- init new calibration value
                  lcd_clear_line(LCD_ROWS - 1)  -- clear bottom line
               else                             -- alarm_repeat action pending
                  nalarm_repeat = nalarm_repeat / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (kbd_count == 0) then
                  nalarm_repeat = key
                  kbd_count = 1
               elsif (nalarm_repeat < 25) then     -- max repeat is 255!
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (nalarm_repeat == 25  &  key < 6) then
                  nalarm_repeat = nalarm_repeat * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  alarm_repeat = nalarm_repeat
                  rtc_set_alarm_repeat(alarm_repeat)
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      KBD_CALIBRATE:                            -- calibration value
         block
            if (key == 10) then                 -- asterisk
               if (kbd_count == 0) then         -- no more input pending
                  kbd_state = KBD_IDLE          -- back to idle menu
               else                             -- calibration setting pending
                  ncalibrate = ncalibrate / 10  -- discard previous key
                  kbd_count = kbd_count - 1     -- backspace
               end if
               lcd_clear_line(LCD_ROWS - 1)     -- clear bottom line
            elsif (key < 10) then               -- numeric
               if (ncalibrate < 25) then         -- max calibration is 255!
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               elsif (ncalibrate == 25  &  key < 6) then
                  ncalibrate = ncalibrate * 10 + key
                  kbd_count = kbd_count + 1     -- progress counter
               end if
            elsif (key == 11) then              -- number sign
               if (kbd_count > 0) then          -- alarm_repeat prepared
                  calibrate = ncalibrate
                  rtc_calibrate(sbyte(calibrate))
               end if
               kbd_count = 0                    -- reset progress counter
               kbd_state = KBD_IDLE             -- reset state
            end if
         end block

      otherwise
         kbd_state = KBD_IDLE                   -- catch menu selection errors

   end case

   return

end procedure

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_set_time_bin - JALlib Procedures Help

rtc_set_time_bin JALLIB PROCEDURE

Signature

procedure rtc_set_time_bin(byte in hh, byte in mm, byte in ss) is

Description

Title: set time (hour, minute, second) in binary notation

Include

To use this procedure, include the library:

include rtc_common

Parameters

  • hh - byte in
  • mm - byte in
  • ss - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_common.jal


rtc_write_dayofmonth - JALlib Procedures Help

rtc_write_dayofmonth JALLIB PROCEDURE

Signature

procedure rtc_write_dayofmonth(byte in dayofmonth) is

Description

Write day of month value in bcd notation to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • dayofmonth - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_dayofweek - JALlib Procedures Help

rtc_write_dayofweek JALLIB PROCEDURE

Signature

procedure rtc_write_dayofweek(byte in dayofweek) is

Description

Write day of week value to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • dayofweek - byte in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_full_year - JALlib Procedures Help

rtc_write_full_year JALLIB PROCEDURE

Signature

procedure rtc_write_full_year(word in year) is

Description

Write year full value in bcd notation to the rtc. The high byte of the
parameter contains the year hunderds in bcd, the low byte the tens years
in bcd.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • year - word in

Return Value

None

Example

From sample file: 16f1825_rtc_ds3231.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the DS3231 RTC Real Time Clock IC.
-- Author: Rob Jansen, Copyright (c) 2021..2023, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample program for controlling the DS3231 RTC Real Time Clock. It
--              sets the time and date and prints the results on the screen via a USART.
--              It also demonstrates the rtc alarm functionality, a DS3231 specific
--              temperature feature and more.
--
include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset internal
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_1111       -- Weak pull-up on all pins.
WPUC = 0b0011_1111       -- Weak pull-up on all pins.
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()      -- All pins digital IO
_usec_delay(100_000)     -- Give the hardware some time to stabilize.

-- Settings for the USART and initialize
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
include print

-- Settings for the IIC interface used by the DS3231.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 4 -- 400kHz
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
include i2c_hardware
-- Now included the RTC library.
include rtc_ds3231

-- Setting to check the alarm on a poll basis or interrupt bases. When
-- defined the alarms are checked using the external interrupt of the PIC.
-- Using the interrupt has its limitations for this rtc as explained in the
-- sample interrupt routine below.
-- const ALARM_ON_INTERRUPT = TRUE

-- LED
alias led is pin_C3 --Pin 7 for 14 pin DIP.
pin_C3_direction = output

-- Variables
var sword temperature
var byte counter = 0
var byte square_wave = RTC_SQUARE_WAVE_1_HZ
var bit alarm_was_given = FALSE

-- Print the current time of the rtc.
procedure print_time() is

   var byte hours, minutes, seconds

   rtc_get_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "H:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " M:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " S:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)

end procedure

-- Print both set alarm times of the rtc.
procedure print_alarm_time() is

   var byte hours, minutes, seconds

   rtc_get_alarm_1_time_bin(hours, minutes, seconds)
   print_string(serial_hw_data, "Alarm 1 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 1 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_string(serial_hw_data, " Alarm 1 set seconds:")
   print_byte_dec(serial_hw_data, seconds)
   print_crlf(serial_hw_data)
   ; Alarm time 2 only has hours and minutes.
   rtc_get_alarm_2_time_bin(hours, minutes)
   print_string(serial_hw_data, "Alarm 2 set hours:")
   print_byte_dec(serial_hw_data, hours)
   print_string(serial_hw_data, " Alarm 2 set minutes:")
   print_byte_dec(serial_hw_data, minutes)
   print_crlf(serial_hw_data)

end procedure

-- Print the current date of the rtc.
procedure print_date() is

   var word fullyear, yearday
   var byte year, month, date, day

   rtc_get_date_bin(year, month, date)
   print_string(serial_hw_data, "Year: ")
   print_byte_dec(serial_hw_data, year)
   print_string(serial_hw_data, " Month: ")
   print_byte_dec(serial_hw_data, month)
   print_string(serial_hw_data, " Day of month: ")
   print_byte_dec(serial_hw_data, date)
   print_crlf(serial_hw_data)

   -- You can calculate the day of the week.
   day = rtc_calc_dayofweek(year, month, date)
   print_string(serial_hw_data, "Day of week (calculated from date): ")
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- This rtc also keeps track of the day of the week but has to be set first.
   rtc_write_dayofweek(day)
   print_string(serial_hw_data, "Day of week from rtc: ")
   day = rtc_read_dayofweek()
   print_byte_dec(serial_hw_data, day)
   print_crlf(serial_hw_data)

   -- You can also calculate the day of the year.
   yearday = rtc_calc_dayofyear(year, month, date)
   print_string(serial_hw_data, "Day of year (calculated from date): ")
   print_word_dec(serial_hw_data, yearday)
   print_crlf(serial_hw_data)

   -- Get and set the full year date in bcd notation.
   fullyear = rtc_read_full_year()
   print_string(serial_hw_data, "Year: ")
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

   -- Change the date to show the century feature.
   -- Switch between two year in different centuries.
   print_string(serial_hw_data, "Changing century: ")
   if (fullyear < 0x2000) then
      fullyear = 0x2021
   else
      fullyear = 0x1992
   end if
   rtc_write_full_year(fullyear)
   fullyear = rtc_read_full_year()
   year = byte(fullyear >> 8)
   print_byte_dec(serial_hw_data, rtc_bcd2bin(year))
   year = byte(fullyear)
   print_word_dec(serial_hw_data, rtc_bcd2bin(year))
   print_crlf(serial_hw_data)

end procedure

-- Alarm routine. When the first alarm is active the LED will be
-- turned on and when the second alarm is active the LED wil be
-- turned off. Also the 32 kHz ouput signal will be turned on and off.
procedure check_alarms() is

   if rtc_alarm_1_flag() then
      clear_rtc_alarm_1_flag()
      led = ON
      rtc_enable_32_khz()
   end if

   if rtc_alarm_2_flag() then
      clear_rtc_alarm_2_flag()
      led = OFF
      rtc_disable_32_khz()
   end if

end procedure

-- Example of handling the alarm on an interrupt basis. Note that we cannot
-- call any of the RTC procedures because it will interfere with the IIC
-- transmission. We can only set a flag that can be checked later. Note that
-- the interrupt is edge triggered. The rtc interrupt stays low as long as
-- the alarm flag of the RTC is set. The INT/SQW pin must be connected to
-- the INT pin of the PIC. In this case we cannot use the SQW signal since
-- it serves as interrupt output of the RTC.
if defined(ALARM_ON_INTERRUPT) then
   procedure alarm_interrupt is pragma interrupt
      if INTCON_INTF then
         INTCON_INTF = FALSE
         alarm_was_given = TRUE
      end if
   end procedure
end if

-- Set and change the square wave output. Only to be used when the alarm
-- check on interrupt is not used since it uses the INT/SQW pin.
procedure change_square_wave() is

   rtc_set_square_wave(square_wave)
   case square_wave of
      RTC_SQUARE_WAVE_1_HZ:  square_wave = RTC_SQUARE_WAVE_1_KHZ
      RTC_SQUARE_WAVE_1_KHZ: square_wave = RTC_SQUARE_WAVE_4_KHZ
      RTC_SQUARE_WAVE_4_KHZ: square_wave = RTC_SQUARE_WAVE_8_KHZ
      RTC_SQUARE_WAVE_8_KHZ: square_wave = RTC_SQUARE_WAVE_1_HZ
   end case

end procedure

-- Main program starts here. Start with initiallization.
i2c_initialize()
serial_hw_init()
rtc_init()
led = OFF

-- Enable interrupts if setting is defined.
if defined(ALARM_ON_INTERRUPT) then
   INTCON_INTE = TRUE
   -- Interrupt on falling edge.
   OPTION_REG_INTEDG = FALSE
   INTCON_GIE = TRUE
   rtc_enable_alarm_1_interrupt()
   rtc_enable_alarm_2_interrupt()
end if

-- Print the currently set alarm time before setting it.
print_alarm_time()

-- Set some intial time hh:mm:ss in binary format and print it.
rtc_set_time_bin(15, 59, 30)
print_time()

-- Set an alarm time 1 to match with hour, minutes, seconds.
rtc_set_alarm_1_rate(RTC_ALARM_1_HOUR_MIN_SEC_MATCH)
-- Alarm time 1, 15 seconds later than the intial set time.
rtc_set_alarm_1_time_bin(15, 59, 45)

-- Set an alarm time 2 to match with hour, minutes.
rtc_set_alarm_2_rate(RTC_ALARM_2_HOUR_MIN_MATCH)
-- Alarm time 2, 30 seconds later than the initial set time.
rtc_set_alarm_2_time_bin(16, 00)

-- Print the alarm time again to see if it is set correctly.
print_alarm_time()

-- Set a date yy:mm:dd in binary format.
rtc_set_date_bin(21,9,25)

forever loop

   -- Print time and date every second.
   _usec_delay(1_000_000)
   print_time()
   print_date()
   print_crlf(serial_hw_data)

   -- Also print the DS3231 Temperature in degrees Celsius.
   temperature = ds3231_get_temperature()
   print_string(serial_hw_data, "Temperature is: ")
   print_sword_dec(serial_hw_data, temperature / 100)
   serial_hw_data = "."
   -- In case of negative temperature do not show negative fraction.
   if (temperature < 0) then
      print_sword_dec(serial_hw_data, -temperature % 100)
   else
      print_sword_dec(serial_hw_data, temperature % 100)
   end if
   print_string(serial_hw_data, " degrees Celsius.\r\n ")
   print_crlf(serial_hw_data)

   -- Two methods to check the alarms although the version using
   -- the interrupt does not add much value because the rtc
   -- cannot be read in the interrupt routine due to the IIC interface.
   if defined(ALARM_ON_INTERRUPT) then
      -- Version using the external interrupt. Here we initiate an
      -- IIC transfer and check which alarm it was.
      if alarm_was_given then
         check_alarms()
         alarm_was_given = FALSE
      end if
   else
      -- Version without using the external interrupt.
      check_alarms()
      -- In this mode we can also change the square wave since
      -- we do not use the INT/SQW pin for the interrupt. Change
      -- it every 3 seconds.
      if (counter == 3) then
         change_square_wave()
         counter = 0
      else
         counter = counter + 1
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_hour - JALlib Procedures Help

rtc_write_hour JALLIB PROCEDURE

Signature

procedure rtc_write_hour(byte in hour) is

Description

Write 24-hour value in bcd notation to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • hour - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_minute - JALlib Procedures Help

rtc_write_minute JALLIB PROCEDURE

Signature

procedure rtc_write_minute(byte in minute) is

Description

Write minute value in bcd notation to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • minute - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_month - JALlib Procedures Help

rtc_write_month JALLIB PROCEDURE

Signature

procedure rtc_write_month(byte in month) is

Description

Write month value in bcd notation to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • month - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_reg_ - JALlib Procedures Help

rtc_write_reg_ JALLIB PROCEDURE

Signature

procedure rtc_write_reg_(byte in register, byte in data) is

Description

Write specified data to a specified register

Include

To use this procedure, include the library:

include rtc_ds1302

Parameters

  • register - byte in
  • data - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds1302.jal


rtc_write_second - JALlib Procedures Help

rtc_write_second JALLIB PROCEDURE

Signature

procedure rtc_write_second(byte in second) is

Description

Write second value in bcd notation to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • second - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtc_write_year - JALlib Procedures Help

rtc_write_year JALLIB PROCEDURE

Signature

procedure rtc_write_year(byte in year) is

Description

Write year value in bcd notation to the rtc.

Include

To use this procedure, include the library:

include rtc_ds3231

Parameters

  • year - byte in

Return Value

None

Example

From sample file: 18f2580_rtc_ds1302_glcd.jal

-- ------------------------------------------------------
-- Title: Test DS1302 rtc clock module
--
-- Author: Rob Hamerling, Copyright (c) 2013..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing rtc_ds1302 with 182580 and graphical LCD
--
-- Sources:
--
-- Notes:
--
-- --------------------------------------------------------

include 18f2580

pragma target clock      8_000_000                  -- xtal frequency

pragma target  OSC       intosc_noclkout            -- internal oscillator
pragma target  WDT       control
pragma target  PWRTE     enabled
pragma target  MCLR      external
pragma target  BROWNOUT  disabled
pragma target  IESO      disabled
pragma target  FCMEN     disabled
pragma target  LVP       enabled
pragma target  DEBUG     disabled

WDTCON_SWDTEN = false                        -- no wdt

OSCCON_IRCF = 0b111                          -- internal oscillator at 8 MHz
OSCCON_SCS  = 0                              -- select primary clock

include delay
include print
include math

-- GRAPHIC_LCD IO definition ------------------------

alias glcd_dataprt     is portB
alias glcd_dataprt_dir is portB_direction

const bit GLCD_REVERSE_DATABITS = TRUE       -- reversed wiring sequence of databits

alias glcd_di  is pin_A2
alias glcd_rw  is pin_A1
alias glcd_e   is pin_A0
alias glcd_cs1 is pin_C5
alias glcd_cs2 is pin_C6
alias glcd_rst is pin_C7

alias glcd_di_direction  is pin_A2_direction
alias glcd_rw_direction  is pin_A1_direction
alias glcd_e_direction   is pin_A0_direction
alias glcd_cs1_direction is pin_C5_direction
alias glcd_cs2_direction is pin_C6_direction
alias glcd_rst_direction is pin_C7_direction

const bit GLCD_CLIPPING = TRUE               -- enable clipping

include glcd_5x7_font                        -- font to be used
include glcd_font                            -- common font stuff
glcd_font_use(FONT_5X7)                      -- activate font

include glcd_ks0108                          -- glcd device dependent library
include glcd_common                          -- common glcd library

delay_100ms(2)				                     -- power on delay

glcd_init()                                  -- initialize display

-- === With the used board the DS1302 is powered by the PIC ===

pin_A7 = 1                                   -- Vcc for DS1302
pin_A6 = 0                                   -- gnd for DS1302
pin_A7_direction = OUTPUT
pin_A6_direction = OUTPUT

-- === DS1302 rtc library setup ===

alias  rtc_sclk  is pin_C0                   -- clock pin
alias  rtc_io    is pin_C1                   -- data pin
alias  rtc_iodir is pin_C1_direction         -- data pin direction
alias  rtc_ce    is pin_C2                   -- CE and clock control (RST)

pin_C0_direction = OUTPUT                    -- clk / sclk  ) fixed output
pin_C2_direction = OUTPUT                    -- rst / CE    )   "     "
                                             -- iodir is controlled by the library

const RTC_DIODE    = 2                       -- Diode:  1 or 2
const RTC_RESISTOR = 8                       -- Resistor: 2 (2K), 4 (4K) or 8 (8K)
                                             -- any other combination of values
                                             -- will not enable trickle charging

include rtc_ds1302                           -- ds1302 rtc library
rtc_init()                                   -- init the ds1302 module

-- display date or time at current coordinates ------------------
procedure display_3bcd(byte in bcd1,
                       byte in bcd2,
                       byte in bcd3,
                       byte in sep) is
   print_byte_hex(glcd, bcd1)
   glcd = sep
   print_byte_hex(glcd, bcd2)
   glcd = sep
   print_byte_hex(glcd, bcd3)
end procedure

--  check and set date and time ---------
const byte set_minute = 0x51
const byte set_second = 0x51

var   byte ram_minute = 0xAA
var   byte ram_second = 0x55

rtc_read_reg_(rtc_reg_ram_ + 0, ram_minute)   -- read 1st byte of ram
rtc_read_reg_(rtc_reg_ram_ + 2, ram_second)   -- read 2nd byte of ram

if ( (ram_second != set_second)  |
     (ram_minute != set_minute) )  then   -- footprint not matching
   rtc_write_year(0x15)
   rtc_write_month(0x05)
   rtc_write_dayofmonth(0x15)
   rtc_write_hour(0x19)
   rtc_write_minute(set_minute)
   rtc_write_second(set_second)
   rtc_write_reg_(rtc_reg_ram_ + 0, set_minute)   -- 1st byte of ram
   rtc_write_reg_(rtc_reg_ram_ + 2, set_second)   -- 2nd byte of ram
end if

--  main line -------------------------

const byte str_chip[] = "DS1302"
const byte str_date[] = "dmy "
const byte str_time[] = "hms "
const byte str_dow[]  = "day "
const byte str_prot[] = "Prt "
const byte str_adow[] = "..SuMoTuWeThFrSa"          -- indexes 1..7 (*2)

glcd_background_color = GLCD_WHITE                  -- background color

glcd_clear_screen()
print_string(glcd, PICTYPE)
glcd = " "
print_string(glcd, str_chip)

var byte x, y
var sword dx, dy, ex, ey, r
y = GLCD_Y_PIXELS / 2                           -- y-coord. clock center
x = GLCD_X_PIXELS - y                           -- x-coord. clock center
r = sword(GLCD_Y_PIXELS / 2 - 2)                -- radius of clock circle
glcd_circle(x, y, byte(r) + 1)                  -- clock border

var byte sec = 0                                -- previous binary values
var byte min = 0
var byte day = 0
var byte newsec, newmin, newday                 -- new binary values

forever loop

   newsec = rtc_second_bin                         -- get second of 'time now'
   if (sec != newsec) then                         -- second value has changed
      glcd_char_goto(0,10)
      print_string(glcd, str_time)
      display_3bcd(rtc_hour_bcd, rtc_minute_bcd, rtc_second_bcd, ":")
      glcd_pen_color = GLCD_WHITE
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- erase previous hand
      sec = rtc_second_bin                         -- new value
      glcd_pen_color = GLCD_BLACK
      polar_to_cartesian(r - 2, sword(sec) * 6 - 90, dx, dy)   -- end point
      glcd_line(x, y, byte(x + dx), byte(y + dy))  -- draw new hand

      newmin = rtc_minute_bin                      -- get minute now
      if (min != newmin) then
         glcd_pen_color = GLCD_WHITE
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ey), byte(y + ey), byte(x + dx), byte(y + dy))  -- erase previous hand
         min = rtc_minute_bin                      -- new value
         glcd_pen_color = GLCD_BLACK
         polar_to_cartesian(r + 1, sword(min) * 6 - 90, dx, dy)   -- begin point
         polar_to_cartesian(r - 1, sword(min) * 6 - 90, ex, ey)   -- end point
         glcd_line(byte(x + ex), byte(y + ey), byte(x + dx), byte(y + dy))  -- draw new hand

         newday = rtc_dayofmonth_bin
         if (day != newday) then                      -- day has changed
            glcd_char_goto(0,20)
            print_string(glcd, str_date)
            display_3bcd(rtc_dayofmonth_bcd, rtc_month_bcd, rtc_year_bcd, "/")
            glcd_char_goto(0,30)
            print_string(glcd, str_dow)
            glcd = str_adow[rtc_dayofweek * 2]
            glcd = str_adow[rtc_dayofweek * 2 + 1]
            glcd_char_goto(0,40)
            print_string(glcd, str_prot)
            print_byte_hex(glcd, rtc_protect_)
         end if
      end if
   end if

   delay_100ms(3)

end loop

Generated by JALlib CHM Help System | Source: rtc_ds3231.jal


rtcc_hw.jal - JALLIB Library Documentation

rtcc_hw.jal JALLIB LIBRARY

Title

Support for builtin RealTimeClockCalendar (RTCC) module of 18FxxJxx.

Author

Rob Hamerling, Copyright (c) 2010..2015, all rights reserved., Adapted-by:

Compiler

2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

RealTimeClock support:
- Routines for control of the buitin Realtime Clock Calendar module of
18fxxj11, 18fxxj50 and other smilar PICs.
.
his library provides the device specific interface for the services
defined in the rtc_common library, ic functions and procedures for
the realtime clock time and date services.
in addition it contains procedures and functions for the alarm and
some other facilities of the RTCC module, like:
.
- rtc_set_alarm() -- enable/disable alarm
- rtc_get_alarm_date_bcd() -- alarm month,day (bcd), no year!
- rtc_set_alarm_date_bcd()
- rtc_get_alarm_time_bcd() -- alarm hour,minute,second (bcd)
- rtc_set_alarm_time_bcd()
- rtc_set_alarm_interval() -- alarm interval (binary)
- rtc_set_alarm_repeat() -- alarm repeat (binary)
- rtc_set_clock() -- enable/disable RTCC module
- rtc_calibrate() -- compensate crystal frequency aberration
- rtc_pin_signal() -- RTCC output pin signal control
.
NOTES: - This library assumes that a 32768 Hz crystal is connected to
the T1OSI/T1OSO pins. Therefore the application program should
specify the RTCC oscillator source configuration bits as:
pragma target RTCOSC T1OSC
=== include the common realtime clock library ===

Constants and Variables

RTC_ALARM_INTERVAL_HALFSECOND - const byte = 0b0000
RTC_ALARM_INTERVAL_SECOND - const byte = 0b0001
RTC_ALARM_INTERVAL_TENSECONDS - const byte = 0b0010
RTC_ALARM_INTERVAL_MINUTE - const byte = 0b0011
RTC_ALARM_INTERVAL_TENMINUTES - const byte = 0b0100
RTC_ALARM_INTERVAL_HOUR - const byte = 0b0101
RTC_ALARM_INTERVAL_DAY - const byte = 0b0110
RTC_ALARM_INTERVAL_WEEK - const byte = 0b0111
RTC_ALARM_INTERVAL_MONTH - const byte = 0b1000
RTC_ALARM_INTERVAL_YEAR - const byte = 0b1001

Routines

  • rtc_calibrate - Procedure
  • rtc_get_alarm_date_bcd - Procedure
  • rtc_get_alarm_time_bcd - Procedure
  • rtc_pin_signal - Procedure
  • rtc_read_dayofmonth - Function returns byte
  • rtc_read_hour - Function returns byte
  • rtc_read_minute - Function returns byte
  • rtc_read_month - Function returns byte
  • rtc_read_second - Function returns byte
  • rtc_read_sync_ - Procedure
  • rtc_read_year - Function returns byte
  • rtc_set_alarm - Procedure
  • rtc_set_alarm_date_bcd - Procedure
  • rtc_set_alarm_interval - Procedure
  • rtc_set_alarm_repeat - Procedure
  • rtc_set_alarm_time_bcd - Procedure
  • rtc_set_clock - Procedure
  • rtc_write_control_ - Procedure
  • rtc_write_dayofmonth - Procedure
  • rtc_write_hour - Procedure
  • rtc_write_minute - Procedure
  • rtc_write_month - Procedure
  • rtc_write_second - Procedure
  • rtc_write_sync_ - Procedure
  • rtc_write_year - Procedure


Scope - JAL Language Syntax Reference

Scope JALV2 SYNTAX

Syntax

BLOCK...END BLOCK, IF...END IF, loops, procedures, functions

Description

Each statement_block creates a new scope. Variables in scope not visible outside it.

Notes

Inner variables shadow outer ones.

Example

VAR BYTE x = 5
IF TRUE THEN
    VAR WORD x = 100  -- shadows outer
END IF
-- outer x still 5

Generated by JAL Syntax Documentation System | Source: DITA


sd_card.jal - JALLIB Library Documentation

sd_card.jal JALLIB LIBRARY

Title

Library for communicating with SD memory cards

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2022, all rights reserved., Adapted-by: Rob Jansen + Matthew Schinkel

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides functions for SD memory cards.

Notes

SD card SPI mode is 1,1
This version works with standard capacity sd cards up to 4gb and
high capacity up to 32 gb. Extended Capacity up to 2TB
may be supported later on.
CRC error checking has been implemented but performance is greatly impacted if used.

Sources

SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
http://www.rjhcoding.com/avrc-sd-interface-3.php

Constants and Variables

SD_BYTE_PER_SECTOR - const word = 512
LARGE_ARRAY_6_SIZE - const dword = 512 -- choose number of array variables
choose number of array variables
LARGE_ARRAY_6_VARIABLE_SIZE - const dword = 1 -- choose bytes size of variables
choose bytes size of variables
SD_USE_CRC - const bit = FALSE
sd_byte_count - var word = 0
sd_sector_count - var word = 0
sd_sector_select - var dword
SD_GO_IDLE_STATE - const byte = 0
SD_SEND_OP_COND - const byte = 1
SD_SEND_IF_COND - const byte = 8 -- for SDHC only
for SDHC only
SD_SEND_CSD - const byte = 9 -- sd sends "Card Specific Data" standard or high capacity
sd sends "Card Specific Data" standard or high capacity
SD_SEND_CID - const byte = 10
SD_STOP_TRANSMISSION - const byte = 12
SD_SEND_STATUS - const byte = 13
SD_SET_BLOCKLEN - const byte = 16
SD_READ_SINGLE_BLOCK - const byte = 17
SD_READ_MULTIPLE_BLOCK - const byte = 18
SD_WRITE_BLOCK - const byte = 24
SD_WRITE_MULTIPLE_BLOCK - const byte = 25
SD_PROGRAM_CSD - const byte = 27
SD_SET_WRITE_PROT - const byte = 28
SD_CLR_WRITE_PROT - const byte = 29
SD_SEND_WRITE_PROT - const byte = 30
SD_ERASE_WR_BLK_START - const byte = 32
SD_ERASE_WR_BLK_END - const byte = 33
SD_ERASE - const byte = 38
SD_APP_CMD - const byte = 55 -- indicate that the next command is a application specific command
indicate that the next command is a application specific command
SD_GEN_CMD - const byte = 56
SD_READ_OCR - const byte = 58
SD_CRC_ON_OFF - const byte = 59 -- default is off
default is off
SD_SD_STATUS - const byte = 13
SD_SEND_NUM_WR_BLOCKS - const byte = 22
SD_SET_WR_BLK_ERASE_COUNT - const byte = 23
SD_SD_APP_OP_COND - const byte = 41
SD_SET_CLR_CARD_DETECT - const byte = 42
SD_SEND_SCR - const byte = 51
SD_IN_IDLE_STATE - const byte = 0
SD_ERASE_RESET - const byte = 1
SD_ILLEGAL_COMMAND - const byte = 2
SD_COM_CRC_ERROR - const byte = 3
SD_ERASE_SEQUENCE_ERROR - const byte = 4
SD_ADDRESS_ERROR - const byte = 5
SD_PARAMETER_ERROR - const byte = 6
sd_card_type - var bit = 0
sd_has_init - var bit = 0
SD_HIGH_CAPACITY - const bit = 0
SD_STANDARD_CAPACITY - const bit = 1
sd_has_error - var bit = 0
sd_error_details - var word = 0
SD_DEVICE_NOT_FOUND - const byte = 0
SD_TYPE_NOT_SUPPORTED - const byte = 1
SD_INIT_FAILURE - const byte = 2
SD_TIMED_OUT - const byte = 3
SD_COMMAND_TIME_OUT - const byte = 4
SD_COMMAND_NOT_SUPPORTED - const byte = 5
SD_READ_ERROR - const byte = 6
SD_WRITE_ERROR - const byte = 7
SD_CRC_ERROR - const byte = 8
SD_COMMAND_CRC_ERROR - const byte = 9
SD_DATA_CRC_ERROR - const byte = 10
SD_READ - const byte = 0
SD_WRITE - const byte = 1
sd_max_retries - var byte = 3
sd_retry_count - var byte = 0
sd_error_count - var dword = 0
sd_success_count - var dword = 0

Routines

  • _sd_read_512 - Procedure
  • _sd_read_512_crc - Procedure
  • _sd_write_512 - Procedure
  • _sd_write_512_crc - Procedure
  • crc_clear_error - Procedure
  • crc_init - Procedure
  • sd_check_crc_errors - Procedure
  • sd_data_byte'get - Function returns byte
  • sd_data_byte'put - Procedure
  • sd_disable - Procedure
  • sd_enable - Procedure
  • sd_error'get - Function returns word
  • sd_error'put - Procedure
  • sd_get_number_of_sectors - Procedure
  • sd_init - Procedure
  • sd_is_inserted - Function returns bit
  • sd_print_enhanced_statistics - Procedure
  • sd_print_error - Procedure
  • sd_print_response - Procedure
  • sd_print_sector - Procedure
  • sd_print_sector_hex - Procedure
  • sd_read_csd_cid - Procedure
  • sd_read_if_cond - Function returns byte
  • sd_read_pulse_byte - Procedure
  • sd_read_sector - Procedure
  • sd_read_sector_address - Procedure
  • sd_read_sector_with_callback - Procedure
  • sd_read_write_next_ready - Function returns byte
  • sd_ready - Function returns byte
  • sd_reset_error_state - Procedure
  • sd_retry_operation - Procedure
  • sd_seperator - Procedure
  • sd_set_idle - Procedure
  • sd_start_read - Procedure
  • sd_start_write - Procedure
  • sd_stop_read - Procedure
  • sd_stop_write - Procedure
  • sd_toggle - Procedure
  • sd_write_pulse - Procedure
  • sd_write_pulse_byte - Procedure
  • sd_write_sector - Procedure
  • sd_write_sector_address - Procedure
  • sd_write_sector_with_callback - Procedure
  • sd_write_to_sector_end - Procedure
  • send_command - Procedure


sd_check_crc_errors - JALlib Procedures Help

sd_check_crc_errors JALLIB PROCEDURE

Signature

procedure sd_check_crc_errors() is

Description

Check for errors and update error statistics
Increments error or success counters based on current error state

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_sd_card_crc.jal

-- Title: Enhanced SD Card Sample with CRC Error Handling (Bitwise Implementation)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Enhanced SD card sample with comprehensive CRC error handling
--              and retry mechanisms for robust SD card communication.
--              Uses CRC16-CCITT bitwise implementation for CRC calculations.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been enhanced with CRC error handling and retry mechanisms.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_USE_CRC = TRUE  -- Set to FALSE to disable CRC validation
-- CRITICAL: Do not change or remove these settings - they are optimized for performance
const bit SD_READ_EXTRA_SPEED = TRUE
const bit SD_WRITE_EXTRA_SPEED = TRUE
include sd_card              -- include the sd card ide hard disk library

-- Include stopwatch for timing measurements
const STOPWATCH_VAR_SIZE = 4
const STOPWATCH_MIN_VALUE = STOPWATCH_MS
const STOPWATCH_USE_TIMER = 1
include stopwatch  -- include enhanced error handling library

-- =============================================================================
-- Enhanced SD Card Operations
-- =============================================================================

-- =============================================================================
-- Main Program
-- =============================================================================

-- Initialize SD card with error handling
print_string(serial_data, "Initializing SD card...")
print_crlf(serial_data)
sd_init()

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD INITIALIZATION FAILED")
   print_crlf(serial_data)
   sd_check_crc_errors()
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!")
   print_crlf(serial_data)
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port (now in library)

-- Send something to the serial port
sd_seperator()             -- send "----" via serial port
print_string(serial_data,"ENHANCED SD CARD SAMPLE WITH CRC ERROR HANDLING")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

-- Shared variables for examples
var dword data_errors = 0
var dword total_tests = 0
var bit data_match = FALSE

-- Example enable/disable flags
const bit ENABLE_EXAMPLE_1 = FALSE  -- 512-byte pattern data test
const bit ENABLE_EXAMPLE_2 = FALSE  -- Alphabet cycling test
const bit ENABLE_EXAMPLE_3 = TRUE   -- 2-sector write/read test
const word TEST_CYCLES = 2          -- Number of write/read cycles for Example #3

sd_seperator()            -- seperate the examples with "----"

-- Report SD size in GiB to avoid overflow on large cards
print_string(serial_data,"SD Card Size (GiB): ")
var dword __sectors = sd_number_of_sectors
var dword __gib = __sectors / 2_097_152   -- 2,097,152 sectors of 512B per GiB
print_dword_dec(serial_data,__gib)
print_crlf(serial_data)

-- Report SD card type
print_string(serial_data, "SD Card Type: ")
if sd_card_type == SD_HIGH_CAPACITY then
   print_string(serial_data, "SDHC/SDXC (High Capacity)")
else
   print_string(serial_data, "SDSC (Standard Capacity)")
end if
print_crlf(serial_data)

sd_seperator()            -- seperate the examples with "----"

--------------------------------------------------------------------------------
-- EXAMPLE #1: 512-byte Pattern Data Test with CRC Validation
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_1 then
print_string(serial_data, "EXAMPLE #1: 512-byte pattern data test - CRC ENABLED")
print_crlf(serial_data)
print_string(serial_data, "Creating 512-byte constant array with predictable pattern...")
print_crlf(serial_data)

-- Create a 512-byte pattern directly in the sector buffer
-- Using a predictable but varied pattern that's easy to verify
var word i
var byte pattern_value = 0x5A  -- Starting pattern value

print_string(serial_data, "Setting starting sector to 20...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(20)  -- Writes to sector 20, then sd_sector_select becomes 0 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)

print_string(serial_data, "Writing 512-byte data to current sector...")
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Fill the sector buffer with a predictable but varied pattern
for 512 using i loop
   sd_sector_buffer[i] = pattern_value
   pattern_value = pattern_value + 1
   if pattern_value == 0 then
      pattern_value = 0x5A  -- Reset to avoid 0x00
   end if
end loop

-- Write the sector with retry mechanism
sd_retry_operation(sd_sector_select, 4)
total_tests = total_tests + 1

if sd_has_error == FALSE then
   print_string(serial_data, "SUCCESS")
   print_crlf(serial_data)

   -- Add small delay between write and read operations
   _usec_delay(100_000) -- 100ms delay

   print_string(serial_data, "Reading back 512-byte data from sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "...")
   print_crlf(serial_data)

   -- Read the sector back directly
   sd_read_sector_address(sd_sector_select)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      print_string(serial_data, "SUCCESS")
      print_crlf(serial_data)

      -- Validate the data matches exactly by recreating the pattern
      var bit data_valid = TRUE
      var byte expected_value = 0x5A  -- Starting pattern value

      for 512 using i loop
         if sd_sector_buffer[i] != expected_value then
            data_valid = FALSE
         end if
         expected_value = expected_value + 1
         if expected_value == 0 then
            expected_value = 0x5A  -- Reset to avoid 0x00
         end if
      end loop

      if data_valid == TRUE then
         print_string(serial_data, "SUCCESS - All 512 bytes verified correctly")
         print_crlf(serial_data)
         print_string(serial_data, "CRC validation passed - Data integrity confirmed!")
         print_crlf(serial_data)
      else
         print_string(serial_data, "FAIL - Data mismatch detected in 512-byte test")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Read operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if
else
   print_string(serial_data, "FAIL - Write operation failed")
   print_crlf(serial_data)
   data_errors = data_errors + 1
end if

-- Stop stopwatch and display timing results
stopwatch_stop()

print_crlf(serial_data)
print_string(serial_data, "=== 512-BYTE PATTERN DATA TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test completed with CRC validation")
print_crlf(serial_data)

-- Display timing information
print_string(serial_data, "Example #1 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_1

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #2: Enhanced alphabet cycling test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_2 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC DISABLED")
end if
print_crlf(serial_data)

-- Variables for alphabet cycling test
var byte current_letter = "A"
var byte test_cycle = 0
var byte max_cycles = 2
var bit data_match = TRUE

print_string(serial_data, "Starting alphabet cycling test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC enabled)")
else
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC disabled)")
end if
print_crlf(serial_data)

print_string(serial_data, "Setting starting sector to 21...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(21)  -- Writes to sector 21, then sd_sector_select becomes 1 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Main test loop - 2 cycles
for max_cycles using test_cycle loop
   -- Fill sector buffer with current letter
   for 512 using step1 loop
      sd_sector_buffer[step1] = current_letter
   end loop

   -- Write sector with retry mechanism
   print_string(serial_data, "Cycle ")
   print_byte_dec(serial_data, test_cycle + 1)
   print_string(serial_data, "/2 - Writing letter '")
   serial_write(current_letter)
   print_string(serial_data, "' to sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "... ")

   sd_retry_operation(sd_sector_select, 4)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Add small delay between write and read operations
      _usec_delay(100_000) -- 100ms delay

      -- Read back sector with retry mechanism
      print_string(serial_data, "Reading back from sector ")
      print_dword_dec(serial_data, sd_sector_select)
      print_string(serial_data, "... ")
      sd_read_sector_address(sd_sector_select)
      total_tests = total_tests + 1

      if sd_has_error == FALSE then
         -- Display first byte of received data for verification
         print_string(serial_data, "Received: ")
         print_byte_hex(serial_data, sd_sector_buffer[0])
         print_crlf(serial_data)

         -- Verify all data matches the expected letter
         data_match = TRUE
         for 512 using step1 loop
            if sd_sector_buffer[step1] != current_letter then
               data_match = FALSE
            end if
         end loop

         if data_match == TRUE then
            print_string(serial_data, "SUCCESS - Data verified")
            print_crlf(serial_data)
         else
            print_string(serial_data, "FAIL - Data mismatch detected")
            print_crlf(serial_data)
            data_errors = data_errors + 1
         end if
      else
         print_string(serial_data, "FAIL - Read operation failed")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Write operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Move to next letter in alphabet
   current_letter = current_letter + 1
   if current_letter > "Z" then
      current_letter = "A"  -- Wrap back to 'A' after 'Z'
   end if

   -- Note: sd_sector_select is automatically incremented by the library after each operation
   print_string(serial_data, "Next sector will be: ")
   print_dword_dec(serial_data, sd_sector_select)
   print_crlf(serial_data)

   -- Small delay between cycles
   _usec_delay(100_000)
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== ALPHABET CYCLING TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #2 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_2

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #3: Looped A/B pattern test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_3 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC DISABLED")
end if
print_crlf(serial_data)

print_string(serial_data, "Starting A/B pattern test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing A/B pattern write/read (CRC enabled)")
else
   print_string(serial_data, "Testing A/B pattern write/read (CRC disabled)")
end if
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Variables for A/B pattern test

-- Variables for looped A/B pattern test
var word cycle_count = 0

print_string(serial_data, "Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " write cycles...")
print_crlf(serial_data)

-- Phase 1: Write A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Write 'A' to sector 23
   for 512 using step1 loop
      sd_sector_buffer[step1] = "A"
   end loop
   sd_retry_operation(23, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Write 'B' to sector 24
   for 512 using step1 loop
      sd_sector_buffer[step1] = "B"
   end loop
   sd_retry_operation(24, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Write progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

print_string(serial_data, "Write phase complete. Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " read cycles...")
print_crlf(serial_data)

-- Add small delay between write and read phases
_usec_delay(100_000) -- 100ms delay

-- Phase 2: Read back A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Read 'A' from sector 23
   sd_retry_operation(23, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'A'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "A" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read A cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Read 'B' from sector 24
   sd_retry_operation(24, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'B'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "B" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read B cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Read progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== LOOPED A/B PATTERN TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test cycles completed: ")
print_word_dec(serial_data, TEST_CYCLES)
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #3 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

-- Calculate and display average time per cycle
var dword average_time_per_cycle = 0
var dword average_cycles_per_cycle = 0

-- Calculate average time per cycle (total time / number of cycles)
average_time_per_cycle = stopwatch / TEST_CYCLES
print_string(serial_data, "Average time per cycle: ")
print_dword_dec(serial_data, average_time_per_cycle)
print_string(serial_data, " ms")
print_crlf(serial_data)

-- Calculate average instruction cycles per cycle
average_cycles_per_cycle = stopwatch_cycles / TEST_CYCLES
print_string(serial_data, "Average instruction cycles per cycle: ")
print_dword_dec(serial_data, average_cycles_per_cycle)
print_crlf(serial_data)

-- Calculate bytes per second
var dword total_bytes_transferred = 0
var dword bytes_per_second = 0
var dword total_seconds = 0

-- Calculate total bytes transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 512 bytes
total_bytes_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
total_bytes_transferred = total_bytes_transferred * 512  -- multiply by bytes_per_operation
total_seconds = stopwatch / 1000  -- Convert milliseconds to seconds
bytes_per_second = total_bytes_transferred / total_seconds

print_string(serial_data, "Total bytes transferred: ")
print_dword_dec(serial_data, total_bytes_transferred)
print_crlf(serial_data)
print_string(serial_data, "Data transfer rate: ")
print_dword_dec(serial_data, bytes_per_second)
print_string(serial_data, " bytes/second")
print_crlf(serial_data)

-- Calculate sectors per second
var dword total_sectors_transferred = 0
var dword sectors_per_second = 0

-- Calculate total sectors transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 1 sector (512 bytes)
total_sectors_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
sectors_per_second = total_sectors_transferred / total_seconds

print_string(serial_data, "Total sectors transferred: ")
print_dword_dec(serial_data, total_sectors_transferred)
print_crlf(serial_data)
print_string(serial_data, "Sector transfer rate: ")
print_dword_dec(serial_data, sectors_per_second)
print_string(serial_data, " sectors/second")
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_3

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- Final Statistics
--------------------------------------------------------------------------------
sd_print_enhanced_statistics()

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)
print_string(serial_hw_data, "#")

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_data_byte'get - JALlib Procedures Help

sd_data_byte'get JALLIB PSEUDO VARIABLE

Signature

function sd_data_byte'get() return byte is

Description

Read one byte from SD card during multi-block read
Pseudo-variable for sequential byte reading

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

byte - Data byte read from SD card

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_data_byte'put - JALlib Procedures Help

sd_data_byte'put JALLIB PSEUDO VARIABLE

Signature

procedure sd_data_byte'put(byte in data_byte) is

Description

Write one byte to SD card during multi-block write
Pseudo-variable for sequential byte writing

Include

To use this procedure, include the library:

include sd_card

Parameters

  • data_byte - byte in - Byte value to write to SD card

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_disable - JALlib Procedures Help

sd_disable JALLIB PROCEDURE

Signature

procedure sd_disable() is

Description

Disable the SD card and release SPI bus
Deactivates chip select and sends final clock pulse

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_enable - JALlib Procedures Help

sd_enable JALLIB PROCEDURE

Signature

procedure sd_enable() is

Description

Enable the SD card for SPI communication
Activates chip select and sends clock pulses to prepare SD card

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_error'get - JALlib Procedures Help

sd_error'get JALLIB PSEUDO VARIABLE

Signature

function sd_error'get() return word is

Description

Read and clear SD card error flags
Returns current error details and resets error state

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

word - Bitmask of error codes that occurred

Example

From sample file: 18f26j50_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f26j50                     -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target IOL1WAY disabled   -- Mapping allowed multiple times during runtime
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)

-- RP6 <-> /SS2
PPS_MAP_SS2IN = RP6

-- RP4 <-> SCK2
PPS_MAP_RP4 = PPS_SCK2
PPS_MAP_SCK2IN = RP4

-- RP1 <-> SDI2
PPS_MAP_SDI2 = RP1

-- RP2 <-> SDO2
PPS_MAP_RP2 = PPS_SDO2

-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b3_direction
alias pin_ss2 is pin_b3
alias pin_sdi2_direction is pin_a1_direction
alias pin_sdo2_direction is pin_a5_direction
alias pin_sck2_direction is pin_b1_direction

-- setup SPI library
include spi_master_hw2         -- includes the spi library
-- define spi inputs/outputs
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
--
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_16) -- init spi, choose mode and speed
alias spi_master is spi_master_hw2
alias spi_master_exchange is spi_master_hw2_exchange
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
-- Alias SPI modes
alias spi_master_hw_set_mode_00 is spi_master_hw2_set_mode_00
alias spi_master_hw_set_mode_11 is spi_master_hw2_set_mode_11

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS2
alias sd_chip_select_direction is pin_SS2_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

sd_error = SD_INIT_FAILURE
sd_error = SD_TIMED_OUT
if sd_has_error == TRUE then
   sd_print_error(serial_data)
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_error'put - JALlib Procedures Help

sd_error'put JALLIB PSEUDO VARIABLE

Signature

procedure sd_error'put(word in error) is

Description

Set SD card error flag
Records error by setting corresponding bit in error details register

Include

To use this procedure, include the library:

include sd_card

Parameters

  • error - word in - Error code number to set (0-15)

Return Value

None

Example

From sample file: 18f26j50_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f26j50                     -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target IOL1WAY disabled   -- Mapping allowed multiple times during runtime
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)

-- RP6 <-> /SS2
PPS_MAP_SS2IN = RP6

-- RP4 <-> SCK2
PPS_MAP_RP4 = PPS_SCK2
PPS_MAP_SCK2IN = RP4

-- RP1 <-> SDI2
PPS_MAP_SDI2 = RP1

-- RP2 <-> SDO2
PPS_MAP_RP2 = PPS_SDO2

-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b3_direction
alias pin_ss2 is pin_b3
alias pin_sdi2_direction is pin_a1_direction
alias pin_sdo2_direction is pin_a5_direction
alias pin_sck2_direction is pin_b1_direction

-- setup SPI library
include spi_master_hw2         -- includes the spi library
-- define spi inputs/outputs
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
--
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_16) -- init spi, choose mode and speed
alias spi_master is spi_master_hw2
alias spi_master_exchange is spi_master_hw2_exchange
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
-- Alias SPI modes
alias spi_master_hw_set_mode_00 is spi_master_hw2_set_mode_00
alias spi_master_hw_set_mode_11 is spi_master_hw2_set_mode_11

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS2
alias sd_chip_select_direction is pin_SS2_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

sd_error = SD_INIT_FAILURE
sd_error = SD_TIMED_OUT
if sd_has_error == TRUE then
   sd_print_error(serial_data)
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_get_number_of_sectors - JALlib Procedures Help

sd_get_number_of_sectors JALLIB PROCEDURE

Signature

procedure sd_get_number_of_sectors() is

Description

Retrieve SD card capacity in sectors
Reads Card-Specific Data (CSD) register to determine total sectors

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_init - JALlib Procedures Help

sd_init JALLIB PROCEDURE

Signature

procedure sd_init() is

Description

Initialize SD card for read/write operations
Detects card type (Standard/High/Extended capacity) and prepares for use

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_is_inserted - JALlib Procedures Help

sd_is_inserted JALLIB FUNCTION

Signature

function sd_is_inserted() return bit is

Description

Check if SD card is present and responsive
Attempts to detect and initialize communication with SD card

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

bit - 1 (TRUE) - SD card detected and responding 0 (FALSE) - SD card not found or not responding

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_print_enhanced_statistics - JALlib Procedures Help

sd_print_enhanced_statistics JALLIB PROCEDURE

Signature

procedure sd_print_enhanced_statistics() is

Description

Print SD card operation statistics
Outputs detailed statistics about SD operations and errors

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_sd_card_crc.jal

-- Title: Enhanced SD Card Sample with CRC Error Handling (Bitwise Implementation)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Enhanced SD card sample with comprehensive CRC error handling
--              and retry mechanisms for robust SD card communication.
--              Uses CRC16-CCITT bitwise implementation for CRC calculations.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been enhanced with CRC error handling and retry mechanisms.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_USE_CRC = TRUE  -- Set to FALSE to disable CRC validation
-- CRITICAL: Do not change or remove these settings - they are optimized for performance
const bit SD_READ_EXTRA_SPEED = TRUE
const bit SD_WRITE_EXTRA_SPEED = TRUE
include sd_card              -- include the sd card ide hard disk library

-- Include stopwatch for timing measurements
const STOPWATCH_VAR_SIZE = 4
const STOPWATCH_MIN_VALUE = STOPWATCH_MS
const STOPWATCH_USE_TIMER = 1
include stopwatch  -- include enhanced error handling library

-- =============================================================================
-- Enhanced SD Card Operations
-- =============================================================================

-- =============================================================================
-- Main Program
-- =============================================================================

-- Initialize SD card with error handling
print_string(serial_data, "Initializing SD card...")
print_crlf(serial_data)
sd_init()

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD INITIALIZATION FAILED")
   print_crlf(serial_data)
   sd_check_crc_errors()
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!")
   print_crlf(serial_data)
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port (now in library)

-- Send something to the serial port
sd_seperator()             -- send "----" via serial port
print_string(serial_data,"ENHANCED SD CARD SAMPLE WITH CRC ERROR HANDLING")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

-- Shared variables for examples
var dword data_errors = 0
var dword total_tests = 0
var bit data_match = FALSE

-- Example enable/disable flags
const bit ENABLE_EXAMPLE_1 = FALSE  -- 512-byte pattern data test
const bit ENABLE_EXAMPLE_2 = FALSE  -- Alphabet cycling test
const bit ENABLE_EXAMPLE_3 = TRUE   -- 2-sector write/read test
const word TEST_CYCLES = 2          -- Number of write/read cycles for Example #3

sd_seperator()            -- seperate the examples with "----"

-- Report SD size in GiB to avoid overflow on large cards
print_string(serial_data,"SD Card Size (GiB): ")
var dword __sectors = sd_number_of_sectors
var dword __gib = __sectors / 2_097_152   -- 2,097,152 sectors of 512B per GiB
print_dword_dec(serial_data,__gib)
print_crlf(serial_data)

-- Report SD card type
print_string(serial_data, "SD Card Type: ")
if sd_card_type == SD_HIGH_CAPACITY then
   print_string(serial_data, "SDHC/SDXC (High Capacity)")
else
   print_string(serial_data, "SDSC (Standard Capacity)")
end if
print_crlf(serial_data)

sd_seperator()            -- seperate the examples with "----"

--------------------------------------------------------------------------------
-- EXAMPLE #1: 512-byte Pattern Data Test with CRC Validation
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_1 then
print_string(serial_data, "EXAMPLE #1: 512-byte pattern data test - CRC ENABLED")
print_crlf(serial_data)
print_string(serial_data, "Creating 512-byte constant array with predictable pattern...")
print_crlf(serial_data)

-- Create a 512-byte pattern directly in the sector buffer
-- Using a predictable but varied pattern that's easy to verify
var word i
var byte pattern_value = 0x5A  -- Starting pattern value

print_string(serial_data, "Setting starting sector to 20...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(20)  -- Writes to sector 20, then sd_sector_select becomes 0 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)

print_string(serial_data, "Writing 512-byte data to current sector...")
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Fill the sector buffer with a predictable but varied pattern
for 512 using i loop
   sd_sector_buffer[i] = pattern_value
   pattern_value = pattern_value + 1
   if pattern_value == 0 then
      pattern_value = 0x5A  -- Reset to avoid 0x00
   end if
end loop

-- Write the sector with retry mechanism
sd_retry_operation(sd_sector_select, 4)
total_tests = total_tests + 1

if sd_has_error == FALSE then
   print_string(serial_data, "SUCCESS")
   print_crlf(serial_data)

   -- Add small delay between write and read operations
   _usec_delay(100_000) -- 100ms delay

   print_string(serial_data, "Reading back 512-byte data from sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "...")
   print_crlf(serial_data)

   -- Read the sector back directly
   sd_read_sector_address(sd_sector_select)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      print_string(serial_data, "SUCCESS")
      print_crlf(serial_data)

      -- Validate the data matches exactly by recreating the pattern
      var bit data_valid = TRUE
      var byte expected_value = 0x5A  -- Starting pattern value

      for 512 using i loop
         if sd_sector_buffer[i] != expected_value then
            data_valid = FALSE
         end if
         expected_value = expected_value + 1
         if expected_value == 0 then
            expected_value = 0x5A  -- Reset to avoid 0x00
         end if
      end loop

      if data_valid == TRUE then
         print_string(serial_data, "SUCCESS - All 512 bytes verified correctly")
         print_crlf(serial_data)
         print_string(serial_data, "CRC validation passed - Data integrity confirmed!")
         print_crlf(serial_data)
      else
         print_string(serial_data, "FAIL - Data mismatch detected in 512-byte test")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Read operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if
else
   print_string(serial_data, "FAIL - Write operation failed")
   print_crlf(serial_data)
   data_errors = data_errors + 1
end if

-- Stop stopwatch and display timing results
stopwatch_stop()

print_crlf(serial_data)
print_string(serial_data, "=== 512-BYTE PATTERN DATA TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test completed with CRC validation")
print_crlf(serial_data)

-- Display timing information
print_string(serial_data, "Example #1 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_1

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #2: Enhanced alphabet cycling test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_2 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC DISABLED")
end if
print_crlf(serial_data)

-- Variables for alphabet cycling test
var byte current_letter = "A"
var byte test_cycle = 0
var byte max_cycles = 2
var bit data_match = TRUE

print_string(serial_data, "Starting alphabet cycling test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC enabled)")
else
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC disabled)")
end if
print_crlf(serial_data)

print_string(serial_data, "Setting starting sector to 21...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(21)  -- Writes to sector 21, then sd_sector_select becomes 1 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Main test loop - 2 cycles
for max_cycles using test_cycle loop
   -- Fill sector buffer with current letter
   for 512 using step1 loop
      sd_sector_buffer[step1] = current_letter
   end loop

   -- Write sector with retry mechanism
   print_string(serial_data, "Cycle ")
   print_byte_dec(serial_data, test_cycle + 1)
   print_string(serial_data, "/2 - Writing letter '")
   serial_write(current_letter)
   print_string(serial_data, "' to sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "... ")

   sd_retry_operation(sd_sector_select, 4)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Add small delay between write and read operations
      _usec_delay(100_000) -- 100ms delay

      -- Read back sector with retry mechanism
      print_string(serial_data, "Reading back from sector ")
      print_dword_dec(serial_data, sd_sector_select)
      print_string(serial_data, "... ")
      sd_read_sector_address(sd_sector_select)
      total_tests = total_tests + 1

      if sd_has_error == FALSE then
         -- Display first byte of received data for verification
         print_string(serial_data, "Received: ")
         print_byte_hex(serial_data, sd_sector_buffer[0])
         print_crlf(serial_data)

         -- Verify all data matches the expected letter
         data_match = TRUE
         for 512 using step1 loop
            if sd_sector_buffer[step1] != current_letter then
               data_match = FALSE
            end if
         end loop

         if data_match == TRUE then
            print_string(serial_data, "SUCCESS - Data verified")
            print_crlf(serial_data)
         else
            print_string(serial_data, "FAIL - Data mismatch detected")
            print_crlf(serial_data)
            data_errors = data_errors + 1
         end if
      else
         print_string(serial_data, "FAIL - Read operation failed")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Write operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Move to next letter in alphabet
   current_letter = current_letter + 1
   if current_letter > "Z" then
      current_letter = "A"  -- Wrap back to 'A' after 'Z'
   end if

   -- Note: sd_sector_select is automatically incremented by the library after each operation
   print_string(serial_data, "Next sector will be: ")
   print_dword_dec(serial_data, sd_sector_select)
   print_crlf(serial_data)

   -- Small delay between cycles
   _usec_delay(100_000)
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== ALPHABET CYCLING TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #2 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_2

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #3: Looped A/B pattern test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_3 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC DISABLED")
end if
print_crlf(serial_data)

print_string(serial_data, "Starting A/B pattern test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing A/B pattern write/read (CRC enabled)")
else
   print_string(serial_data, "Testing A/B pattern write/read (CRC disabled)")
end if
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Variables for A/B pattern test

-- Variables for looped A/B pattern test
var word cycle_count = 0

print_string(serial_data, "Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " write cycles...")
print_crlf(serial_data)

-- Phase 1: Write A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Write 'A' to sector 23
   for 512 using step1 loop
      sd_sector_buffer[step1] = "A"
   end loop
   sd_retry_operation(23, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Write 'B' to sector 24
   for 512 using step1 loop
      sd_sector_buffer[step1] = "B"
   end loop
   sd_retry_operation(24, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Write progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

print_string(serial_data, "Write phase complete. Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " read cycles...")
print_crlf(serial_data)

-- Add small delay between write and read phases
_usec_delay(100_000) -- 100ms delay

-- Phase 2: Read back A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Read 'A' from sector 23
   sd_retry_operation(23, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'A'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "A" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read A cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Read 'B' from sector 24
   sd_retry_operation(24, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'B'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "B" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read B cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Read progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== LOOPED A/B PATTERN TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test cycles completed: ")
print_word_dec(serial_data, TEST_CYCLES)
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #3 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

-- Calculate and display average time per cycle
var dword average_time_per_cycle = 0
var dword average_cycles_per_cycle = 0

-- Calculate average time per cycle (total time / number of cycles)
average_time_per_cycle = stopwatch / TEST_CYCLES
print_string(serial_data, "Average time per cycle: ")
print_dword_dec(serial_data, average_time_per_cycle)
print_string(serial_data, " ms")
print_crlf(serial_data)

-- Calculate average instruction cycles per cycle
average_cycles_per_cycle = stopwatch_cycles / TEST_CYCLES
print_string(serial_data, "Average instruction cycles per cycle: ")
print_dword_dec(serial_data, average_cycles_per_cycle)
print_crlf(serial_data)

-- Calculate bytes per second
var dword total_bytes_transferred = 0
var dword bytes_per_second = 0
var dword total_seconds = 0

-- Calculate total bytes transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 512 bytes
total_bytes_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
total_bytes_transferred = total_bytes_transferred * 512  -- multiply by bytes_per_operation
total_seconds = stopwatch / 1000  -- Convert milliseconds to seconds
bytes_per_second = total_bytes_transferred / total_seconds

print_string(serial_data, "Total bytes transferred: ")
print_dword_dec(serial_data, total_bytes_transferred)
print_crlf(serial_data)
print_string(serial_data, "Data transfer rate: ")
print_dword_dec(serial_data, bytes_per_second)
print_string(serial_data, " bytes/second")
print_crlf(serial_data)

-- Calculate sectors per second
var dword total_sectors_transferred = 0
var dword sectors_per_second = 0

-- Calculate total sectors transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 1 sector (512 bytes)
total_sectors_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
sectors_per_second = total_sectors_transferred / total_seconds

print_string(serial_data, "Total sectors transferred: ")
print_dword_dec(serial_data, total_sectors_transferred)
print_crlf(serial_data)
print_string(serial_data, "Sector transfer rate: ")
print_dword_dec(serial_data, sectors_per_second)
print_string(serial_data, " sectors/second")
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_3

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- Final Statistics
--------------------------------------------------------------------------------
sd_print_enhanced_statistics()

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)
print_string(serial_hw_data, "#")

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_print_error - JALlib Procedures Help

sd_print_error JALLIB PROCEDURE

Signature

procedure sd_print_error(volatile byte out device) is

Description

Print human-readable SD card error messages
Outputs all current error flags without clearing error state

Include

To use this procedure, include the library:

include sd_card

Parameters

  • device - byte out - Output device for printing (e.g., serial port)

Return Value

None

Example

From sample file: 18f26j50_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f26j50                     -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target IOL1WAY disabled   -- Mapping allowed multiple times during runtime
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- -----------------------------------------------------------------
-- Configure Remappable Pins on MSSP2 to match SPI/SD-Card wiring,
-- configure MSSP2 and initialize SD-card library
-- -----------------------------------------------------------------
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)

-- RP6 <-> /SS2
PPS_MAP_SS2IN = RP6

-- RP4 <-> SCK2
PPS_MAP_RP4 = PPS_SCK2
PPS_MAP_SCK2IN = RP4

-- RP1 <-> SDI2
PPS_MAP_SDI2 = RP1

-- RP2 <-> SDO2
PPS_MAP_RP2 = PPS_SDO2

-- PPS configuration is done, we can lock again
pps_control_lock(true)

-- Now specify SPI pins aliases
alias pin_ss2_direction is pin_b3_direction
alias pin_ss2 is pin_b3
alias pin_sdi2_direction is pin_a1_direction
alias pin_sdo2_direction is pin_a5_direction
alias pin_sck2_direction is pin_b1_direction

-- setup SPI library
include spi_master_hw2         -- includes the spi library
-- define spi inputs/outputs
pin_sdi2_direction = input    -- spi input
pin_sdo2_direction = output   -- spi output
pin_sck2_direction = output   -- spi clock
--
spi2_init(SPI_MODE_11,SPI_RATE_FOSC_16) -- init spi, choose mode and speed
alias spi_master is spi_master_hw2
alias spi_master_exchange is spi_master_hw2_exchange
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
-- Alias SPI modes
alias spi_master_hw_set_mode_00 is spi_master_hw2_set_mode_00
alias spi_master_hw_set_mode_11 is spi_master_hw2_set_mode_11

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup the sd card pins
alias sd_chip_select is pin_SS2
alias sd_chip_select_direction is pin_SS2_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_ALWAYS_SET_SPI_MODE = TRUE
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

sd_error = SD_INIT_FAILURE
sd_error = SD_TIMED_OUT
if sd_has_error == TRUE then
   sd_print_error(serial_data)
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_print_response - JALlib Procedures Help

sd_print_response JALLIB PROCEDURE

Signature

procedure sd_print_response(volatile byte out device,byte in response) is

Description

Print human-readable SD card R1 response byte
Decodes and displays R1 response status flags

Include

To use this procedure, include the library:

include sd_card

Parameters

  • device - byte out - Output device for printing (e.g., serial port)
  • response - byte in - R1 response byte from SD card

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_print_sector - JALlib Procedures Help

sd_print_sector JALLIB PROCEDURE

Signature

procedure sd_print_sector(volatile byte out device, dword in address) is

Description

Print sector data to output device
Reads and outputs raw sector bytes

Include

To use this procedure, include the library:

include sd_card

Parameters

  • device - byte out - Output device for printing (e.g., serial port)
  • address - dword in - Sector number to read and print

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_print_sector_hex - JALlib Procedures Help

sd_print_sector_hex JALLIB PROCEDURE

Signature

procedure sd_print_sector_hex(volatile byte out device,word in bytes_per_line,dword in address) is

Description

Print sector data in hexadecimal format
Reads and outputs sector bytes as formatted hex values

Include

To use this procedure, include the library:

include sd_card

Parameters

  • device - byte out - Output device for printing (e.g., serial port)
  • bytes_per_line - word in - Number of hex bytes per line (must divide evenly into 512)
  • address - dword in - Sector number to read and print

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_csd_cid - JALlib Procedures Help

sd_read_csd_cid JALLIB PROCEDURE

Signature

procedure sd_read_csd_cid(byte in command) is

Description

Print sector data in hexadecimal format
Reads and outputs sector bytes as formatted hex values

Include

To use this procedure, include the library:

include sd_card

Parameters

  • command - byte in

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_if_cond - JALlib Procedures Help

sd_read_if_cond JALLIB FUNCTION

Signature

function sd_read_if_cond() return byte is

Description

Check if SD card is ready after initialization
Polls SD card using SEND_OP_COND command until ready or timeout

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

byte - 1 - SD card is ready 0 - SD card not ready (timeout occurred)

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_pulse_byte - JALlib Procedures Help

sd_read_pulse_byte JALLIB PROCEDURE

Signature

procedure sd_read_pulse_byte(word in count1) is

Description

Skip forward by reading and discarding bytes
Advances read position without returning data

Include

To use this procedure, include the library:

include sd_card

Parameters

  • count1 - word in - Number of bytes to skip

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_sector - JALlib Procedures Help

sd_read_sector JALLIB PROCEDURE

Signature

procedure sd_read_sector() is

Description

Read one complete 512-byte sector into buffer
Reads entire sector from current position into sd_sector_buffer

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_sector_address - JALlib Procedures Help

sd_read_sector_address JALLIB PROCEDURE

Signature

procedure sd_read_sector_address(dword in address) is

Description

Read single sector at specified address
Convenience function combining start, read, and stop operations

Include

To use this procedure, include the library:

include sd_card

Parameters

  • address - dword in - Sector number to read from

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_sector_with_callback - JALlib Procedures Help

sd_read_sector_with_callback JALLIB PROCEDURE

Signature

procedure sd_read_sector_with_callback(word in chunk_size) is

Description

Read sector in chunks using callback function
Allows user-provided callback to handle data as it's read

Include

To use this procedure, include the library:

include sd_card

Parameters

  • chunk_size - word in - Number of bytes per callback (must divide evenly into 512)

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_read_write_next_ready - JALlib Procedures Help

sd_read_write_next_ready JALLIB FUNCTION

Signature

function sd_read_write_next_ready(byte in read_write) return byte is

Description

Wait for SD card to be ready for next byte transfer
Checks for data ready token at start of each sector

Include

To use this procedure, include the library:

include sd_card

Parameters

  • read_write - byte in - Operation type (SD_READ or SD_WRITE)

Return Value

byte - 1 - SD card is ready for next byte 0 - Timeout waiting for ready signal

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_ready - JALlib Procedures Help

sd_ready JALLIB FUNCTION

Signature

function sd_ready() return byte is

Description

Check if SD card is ready after initialization
Polls SD card using SEND_OP_COND command until ready or timeout

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

byte - 1 - SD card is ready 0 - SD card not ready (timeout occurred)

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_reset_error_state - JALlib Procedures Help

sd_reset_error_state JALLIB PROCEDURE

Signature

procedure sd_reset_error_state() is

Description

Reset SD card error flags
Clears all error state for retry operations

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_retry_operation - JALlib Procedures Help

sd_retry_operation JALLIB PROCEDURE

Signature

procedure sd_retry_operation(dword in sector_address, byte in operation_type) is

Description

Retry failed SD card operation with automatic error recovery
Attempts operation up to sd_max_retries times

Include

To use this procedure, include the library:

include sd_card

Parameters

  • sector_address - dword in - Sector number for operation
  • operation_type - byte in - Type of operation (1=read, 2=write)

Return Value

None

Example

From sample file: 18f67j50_sd_card_crc.jal

-- Title: Enhanced SD Card Sample with CRC Error Handling (Bitwise Implementation)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Enhanced SD card sample with comprehensive CRC error handling
--              and retry mechanisms for robust SD card communication.
--              Uses CRC16-CCITT bitwise implementation for CRC calculations.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been enhanced with CRC error handling and retry mechanisms.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_USE_CRC = TRUE  -- Set to FALSE to disable CRC validation
-- CRITICAL: Do not change or remove these settings - they are optimized for performance
const bit SD_READ_EXTRA_SPEED = TRUE
const bit SD_WRITE_EXTRA_SPEED = TRUE
include sd_card              -- include the sd card ide hard disk library

-- Include stopwatch for timing measurements
const STOPWATCH_VAR_SIZE = 4
const STOPWATCH_MIN_VALUE = STOPWATCH_MS
const STOPWATCH_USE_TIMER = 1
include stopwatch  -- include enhanced error handling library

-- =============================================================================
-- Enhanced SD Card Operations
-- =============================================================================

-- =============================================================================
-- Main Program
-- =============================================================================

-- Initialize SD card with error handling
print_string(serial_data, "Initializing SD card...")
print_crlf(serial_data)
sd_init()

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD INITIALIZATION FAILED")
   print_crlf(serial_data)
   sd_check_crc_errors()
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!")
   print_crlf(serial_data)
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port (now in library)

-- Send something to the serial port
sd_seperator()             -- send "----" via serial port
print_string(serial_data,"ENHANCED SD CARD SAMPLE WITH CRC ERROR HANDLING")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

-- Shared variables for examples
var dword data_errors = 0
var dword total_tests = 0
var bit data_match = FALSE

-- Example enable/disable flags
const bit ENABLE_EXAMPLE_1 = FALSE  -- 512-byte pattern data test
const bit ENABLE_EXAMPLE_2 = FALSE  -- Alphabet cycling test
const bit ENABLE_EXAMPLE_3 = TRUE   -- 2-sector write/read test
const word TEST_CYCLES = 2          -- Number of write/read cycles for Example #3

sd_seperator()            -- seperate the examples with "----"

-- Report SD size in GiB to avoid overflow on large cards
print_string(serial_data,"SD Card Size (GiB): ")
var dword __sectors = sd_number_of_sectors
var dword __gib = __sectors / 2_097_152   -- 2,097,152 sectors of 512B per GiB
print_dword_dec(serial_data,__gib)
print_crlf(serial_data)

-- Report SD card type
print_string(serial_data, "SD Card Type: ")
if sd_card_type == SD_HIGH_CAPACITY then
   print_string(serial_data, "SDHC/SDXC (High Capacity)")
else
   print_string(serial_data, "SDSC (Standard Capacity)")
end if
print_crlf(serial_data)

sd_seperator()            -- seperate the examples with "----"

--------------------------------------------------------------------------------
-- EXAMPLE #1: 512-byte Pattern Data Test with CRC Validation
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_1 then
print_string(serial_data, "EXAMPLE #1: 512-byte pattern data test - CRC ENABLED")
print_crlf(serial_data)
print_string(serial_data, "Creating 512-byte constant array with predictable pattern...")
print_crlf(serial_data)

-- Create a 512-byte pattern directly in the sector buffer
-- Using a predictable but varied pattern that's easy to verify
var word i
var byte pattern_value = 0x5A  -- Starting pattern value

print_string(serial_data, "Setting starting sector to 20...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(20)  -- Writes to sector 20, then sd_sector_select becomes 0 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)

print_string(serial_data, "Writing 512-byte data to current sector...")
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Fill the sector buffer with a predictable but varied pattern
for 512 using i loop
   sd_sector_buffer[i] = pattern_value
   pattern_value = pattern_value + 1
   if pattern_value == 0 then
      pattern_value = 0x5A  -- Reset to avoid 0x00
   end if
end loop

-- Write the sector with retry mechanism
sd_retry_operation(sd_sector_select, 4)
total_tests = total_tests + 1

if sd_has_error == FALSE then
   print_string(serial_data, "SUCCESS")
   print_crlf(serial_data)

   -- Add small delay between write and read operations
   _usec_delay(100_000) -- 100ms delay

   print_string(serial_data, "Reading back 512-byte data from sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "...")
   print_crlf(serial_data)

   -- Read the sector back directly
   sd_read_sector_address(sd_sector_select)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      print_string(serial_data, "SUCCESS")
      print_crlf(serial_data)

      -- Validate the data matches exactly by recreating the pattern
      var bit data_valid = TRUE
      var byte expected_value = 0x5A  -- Starting pattern value

      for 512 using i loop
         if sd_sector_buffer[i] != expected_value then
            data_valid = FALSE
         end if
         expected_value = expected_value + 1
         if expected_value == 0 then
            expected_value = 0x5A  -- Reset to avoid 0x00
         end if
      end loop

      if data_valid == TRUE then
         print_string(serial_data, "SUCCESS - All 512 bytes verified correctly")
         print_crlf(serial_data)
         print_string(serial_data, "CRC validation passed - Data integrity confirmed!")
         print_crlf(serial_data)
      else
         print_string(serial_data, "FAIL - Data mismatch detected in 512-byte test")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Read operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if
else
   print_string(serial_data, "FAIL - Write operation failed")
   print_crlf(serial_data)
   data_errors = data_errors + 1
end if

-- Stop stopwatch and display timing results
stopwatch_stop()

print_crlf(serial_data)
print_string(serial_data, "=== 512-BYTE PATTERN DATA TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test completed with CRC validation")
print_crlf(serial_data)

-- Display timing information
print_string(serial_data, "Example #1 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_1

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #2: Enhanced alphabet cycling test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_2 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC DISABLED")
end if
print_crlf(serial_data)

-- Variables for alphabet cycling test
var byte current_letter = "A"
var byte test_cycle = 0
var byte max_cycles = 2
var bit data_match = TRUE

print_string(serial_data, "Starting alphabet cycling test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC enabled)")
else
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC disabled)")
end if
print_crlf(serial_data)

print_string(serial_data, "Setting starting sector to 21...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(21)  -- Writes to sector 21, then sd_sector_select becomes 1 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Main test loop - 2 cycles
for max_cycles using test_cycle loop
   -- Fill sector buffer with current letter
   for 512 using step1 loop
      sd_sector_buffer[step1] = current_letter
   end loop

   -- Write sector with retry mechanism
   print_string(serial_data, "Cycle ")
   print_byte_dec(serial_data, test_cycle + 1)
   print_string(serial_data, "/2 - Writing letter '")
   serial_write(current_letter)
   print_string(serial_data, "' to sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "... ")

   sd_retry_operation(sd_sector_select, 4)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Add small delay between write and read operations
      _usec_delay(100_000) -- 100ms delay

      -- Read back sector with retry mechanism
      print_string(serial_data, "Reading back from sector ")
      print_dword_dec(serial_data, sd_sector_select)
      print_string(serial_data, "... ")
      sd_read_sector_address(sd_sector_select)
      total_tests = total_tests + 1

      if sd_has_error == FALSE then
         -- Display first byte of received data for verification
         print_string(serial_data, "Received: ")
         print_byte_hex(serial_data, sd_sector_buffer[0])
         print_crlf(serial_data)

         -- Verify all data matches the expected letter
         data_match = TRUE
         for 512 using step1 loop
            if sd_sector_buffer[step1] != current_letter then
               data_match = FALSE
            end if
         end loop

         if data_match == TRUE then
            print_string(serial_data, "SUCCESS - Data verified")
            print_crlf(serial_data)
         else
            print_string(serial_data, "FAIL - Data mismatch detected")
            print_crlf(serial_data)
            data_errors = data_errors + 1
         end if
      else
         print_string(serial_data, "FAIL - Read operation failed")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Write operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Move to next letter in alphabet
   current_letter = current_letter + 1
   if current_letter > "Z" then
      current_letter = "A"  -- Wrap back to 'A' after 'Z'
   end if

   -- Note: sd_sector_select is automatically incremented by the library after each operation
   print_string(serial_data, "Next sector will be: ")
   print_dword_dec(serial_data, sd_sector_select)
   print_crlf(serial_data)

   -- Small delay between cycles
   _usec_delay(100_000)
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== ALPHABET CYCLING TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #2 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_2

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #3: Looped A/B pattern test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_3 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC DISABLED")
end if
print_crlf(serial_data)

print_string(serial_data, "Starting A/B pattern test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing A/B pattern write/read (CRC enabled)")
else
   print_string(serial_data, "Testing A/B pattern write/read (CRC disabled)")
end if
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Variables for A/B pattern test

-- Variables for looped A/B pattern test
var word cycle_count = 0

print_string(serial_data, "Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " write cycles...")
print_crlf(serial_data)

-- Phase 1: Write A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Write 'A' to sector 23
   for 512 using step1 loop
      sd_sector_buffer[step1] = "A"
   end loop
   sd_retry_operation(23, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Write 'B' to sector 24
   for 512 using step1 loop
      sd_sector_buffer[step1] = "B"
   end loop
   sd_retry_operation(24, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Write progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

print_string(serial_data, "Write phase complete. Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " read cycles...")
print_crlf(serial_data)

-- Add small delay between write and read phases
_usec_delay(100_000) -- 100ms delay

-- Phase 2: Read back A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Read 'A' from sector 23
   sd_retry_operation(23, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'A'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "A" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read A cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Read 'B' from sector 24
   sd_retry_operation(24, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'B'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "B" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read B cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Read progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== LOOPED A/B PATTERN TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test cycles completed: ")
print_word_dec(serial_data, TEST_CYCLES)
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #3 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

-- Calculate and display average time per cycle
var dword average_time_per_cycle = 0
var dword average_cycles_per_cycle = 0

-- Calculate average time per cycle (total time / number of cycles)
average_time_per_cycle = stopwatch / TEST_CYCLES
print_string(serial_data, "Average time per cycle: ")
print_dword_dec(serial_data, average_time_per_cycle)
print_string(serial_data, " ms")
print_crlf(serial_data)

-- Calculate average instruction cycles per cycle
average_cycles_per_cycle = stopwatch_cycles / TEST_CYCLES
print_string(serial_data, "Average instruction cycles per cycle: ")
print_dword_dec(serial_data, average_cycles_per_cycle)
print_crlf(serial_data)

-- Calculate bytes per second
var dword total_bytes_transferred = 0
var dword bytes_per_second = 0
var dword total_seconds = 0

-- Calculate total bytes transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 512 bytes
total_bytes_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
total_bytes_transferred = total_bytes_transferred * 512  -- multiply by bytes_per_operation
total_seconds = stopwatch / 1000  -- Convert milliseconds to seconds
bytes_per_second = total_bytes_transferred / total_seconds

print_string(serial_data, "Total bytes transferred: ")
print_dword_dec(serial_data, total_bytes_transferred)
print_crlf(serial_data)
print_string(serial_data, "Data transfer rate: ")
print_dword_dec(serial_data, bytes_per_second)
print_string(serial_data, " bytes/second")
print_crlf(serial_data)

-- Calculate sectors per second
var dword total_sectors_transferred = 0
var dword sectors_per_second = 0

-- Calculate total sectors transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 1 sector (512 bytes)
total_sectors_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
sectors_per_second = total_sectors_transferred / total_seconds

print_string(serial_data, "Total sectors transferred: ")
print_dword_dec(serial_data, total_sectors_transferred)
print_crlf(serial_data)
print_string(serial_data, "Sector transfer rate: ")
print_dword_dec(serial_data, sectors_per_second)
print_string(serial_data, " sectors/second")
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_3

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- Final Statistics
--------------------------------------------------------------------------------
sd_print_enhanced_statistics()

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)
print_string(serial_hw_data, "#")

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_seperator - JALlib Procedures Help

sd_seperator JALLIB PROCEDURE

Signature

procedure sd_seperator() is

Description

Print separator line for debug output
Outputs visual separator for debugging messages

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_sd_card_crc.jal

-- Title: Enhanced SD Card Sample with CRC Error Handling (Bitwise Implementation)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Compiler: >=2.4r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Enhanced SD card sample with comprehensive CRC error handling
--              and retry mechanisms for robust SD card communication.
--              Uses CRC16-CCITT bitwise implementation for CRC calculations.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been enhanced with CRC error handling and retry mechanisms.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 9600   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
const bit SD_USE_CRC = TRUE  -- Set to FALSE to disable CRC validation
-- CRITICAL: Do not change or remove these settings - they are optimized for performance
const bit SD_READ_EXTRA_SPEED = TRUE
const bit SD_WRITE_EXTRA_SPEED = TRUE
include sd_card              -- include the sd card ide hard disk library

-- Include stopwatch for timing measurements
const STOPWATCH_VAR_SIZE = 4
const STOPWATCH_MIN_VALUE = STOPWATCH_MS
const STOPWATCH_USE_TIMER = 1
include stopwatch  -- include enhanced error handling library

-- =============================================================================
-- Enhanced SD Card Operations
-- =============================================================================

-- =============================================================================
-- Main Program
-- =============================================================================

-- Initialize SD card with error handling
print_string(serial_data, "Initializing SD card...")
print_crlf(serial_data)
sd_init()

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD INITIALIZATION FAILED")
   print_crlf(serial_data)
   sd_check_crc_errors()
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!")
   print_crlf(serial_data)
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port (now in library)

-- Send something to the serial port
sd_seperator()             -- send "----" via serial port
print_string(serial_data,"ENHANCED SD CARD SAMPLE WITH CRC ERROR HANDLING")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

-- Shared variables for examples
var dword data_errors = 0
var dword total_tests = 0
var bit data_match = FALSE

-- Example enable/disable flags
const bit ENABLE_EXAMPLE_1 = FALSE  -- 512-byte pattern data test
const bit ENABLE_EXAMPLE_2 = FALSE  -- Alphabet cycling test
const bit ENABLE_EXAMPLE_3 = TRUE   -- 2-sector write/read test
const word TEST_CYCLES = 2          -- Number of write/read cycles for Example #3

sd_seperator()            -- seperate the examples with "----"

-- Report SD size in GiB to avoid overflow on large cards
print_string(serial_data,"SD Card Size (GiB): ")
var dword __sectors = sd_number_of_sectors
var dword __gib = __sectors / 2_097_152   -- 2,097,152 sectors of 512B per GiB
print_dword_dec(serial_data,__gib)
print_crlf(serial_data)

-- Report SD card type
print_string(serial_data, "SD Card Type: ")
if sd_card_type == SD_HIGH_CAPACITY then
   print_string(serial_data, "SDHC/SDXC (High Capacity)")
else
   print_string(serial_data, "SDSC (Standard Capacity)")
end if
print_crlf(serial_data)

sd_seperator()            -- seperate the examples with "----"

--------------------------------------------------------------------------------
-- EXAMPLE #1: 512-byte Pattern Data Test with CRC Validation
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_1 then
print_string(serial_data, "EXAMPLE #1: 512-byte pattern data test - CRC ENABLED")
print_crlf(serial_data)
print_string(serial_data, "Creating 512-byte constant array with predictable pattern...")
print_crlf(serial_data)

-- Create a 512-byte pattern directly in the sector buffer
-- Using a predictable but varied pattern that's easy to verify
var word i
var byte pattern_value = 0x5A  -- Starting pattern value

print_string(serial_data, "Setting starting sector to 20...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(20)  -- Writes to sector 20, then sd_sector_select becomes 0 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)

print_string(serial_data, "Writing 512-byte data to current sector...")
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Fill the sector buffer with a predictable but varied pattern
for 512 using i loop
   sd_sector_buffer[i] = pattern_value
   pattern_value = pattern_value + 1
   if pattern_value == 0 then
      pattern_value = 0x5A  -- Reset to avoid 0x00
   end if
end loop

-- Write the sector with retry mechanism
sd_retry_operation(sd_sector_select, 4)
total_tests = total_tests + 1

if sd_has_error == FALSE then
   print_string(serial_data, "SUCCESS")
   print_crlf(serial_data)

   -- Add small delay between write and read operations
   _usec_delay(100_000) -- 100ms delay

   print_string(serial_data, "Reading back 512-byte data from sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "...")
   print_crlf(serial_data)

   -- Read the sector back directly
   sd_read_sector_address(sd_sector_select)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      print_string(serial_data, "SUCCESS")
      print_crlf(serial_data)

      -- Validate the data matches exactly by recreating the pattern
      var bit data_valid = TRUE
      var byte expected_value = 0x5A  -- Starting pattern value

      for 512 using i loop
         if sd_sector_buffer[i] != expected_value then
            data_valid = FALSE
         end if
         expected_value = expected_value + 1
         if expected_value == 0 then
            expected_value = 0x5A  -- Reset to avoid 0x00
         end if
      end loop

      if data_valid == TRUE then
         print_string(serial_data, "SUCCESS - All 512 bytes verified correctly")
         print_crlf(serial_data)
         print_string(serial_data, "CRC validation passed - Data integrity confirmed!")
         print_crlf(serial_data)
      else
         print_string(serial_data, "FAIL - Data mismatch detected in 512-byte test")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Read operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if
else
   print_string(serial_data, "FAIL - Write operation failed")
   print_crlf(serial_data)
   data_errors = data_errors + 1
end if

-- Stop stopwatch and display timing results
stopwatch_stop()

print_crlf(serial_data)
print_string(serial_data, "=== 512-BYTE PATTERN DATA TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test completed with CRC validation")
print_crlf(serial_data)

-- Display timing information
print_string(serial_data, "Example #1 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_1

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #2: Enhanced alphabet cycling test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_2 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #2: Alphabet cycling test (2 cycles A-Z) - CRC DISABLED")
end if
print_crlf(serial_data)

-- Variables for alphabet cycling test
var byte current_letter = "A"
var byte test_cycle = 0
var byte max_cycles = 2
var bit data_match = TRUE

print_string(serial_data, "Starting alphabet cycling test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC enabled)")
else
   print_string(serial_data, "Testing 2 cycles of letters A through Z (CRC disabled)")
end if
print_crlf(serial_data)

print_string(serial_data, "Setting starting sector to 21...")
print_crlf(serial_data)

-- Set the starting sector
sd_write_sector_address(21)  -- Writes to sector 21, then sd_sector_select becomes 1 for next operation
print_string(serial_data, "Current sector is now: ")
print_dword_dec(serial_data, sd_sector_select)
print_crlf(serial_data)
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Main test loop - 2 cycles
for max_cycles using test_cycle loop
   -- Fill sector buffer with current letter
   for 512 using step1 loop
      sd_sector_buffer[step1] = current_letter
   end loop

   -- Write sector with retry mechanism
   print_string(serial_data, "Cycle ")
   print_byte_dec(serial_data, test_cycle + 1)
   print_string(serial_data, "/2 - Writing letter '")
   serial_write(current_letter)
   print_string(serial_data, "' to sector ")
   print_dword_dec(serial_data, sd_sector_select)
   print_string(serial_data, "... ")

   sd_retry_operation(sd_sector_select, 4)
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Add small delay between write and read operations
      _usec_delay(100_000) -- 100ms delay

      -- Read back sector with retry mechanism
      print_string(serial_data, "Reading back from sector ")
      print_dword_dec(serial_data, sd_sector_select)
      print_string(serial_data, "... ")
      sd_read_sector_address(sd_sector_select)
      total_tests = total_tests + 1

      if sd_has_error == FALSE then
         -- Display first byte of received data for verification
         print_string(serial_data, "Received: ")
         print_byte_hex(serial_data, sd_sector_buffer[0])
         print_crlf(serial_data)

         -- Verify all data matches the expected letter
         data_match = TRUE
         for 512 using step1 loop
            if sd_sector_buffer[step1] != current_letter then
               data_match = FALSE
            end if
         end loop

         if data_match == TRUE then
            print_string(serial_data, "SUCCESS - Data verified")
            print_crlf(serial_data)
         else
            print_string(serial_data, "FAIL - Data mismatch detected")
            print_crlf(serial_data)
            data_errors = data_errors + 1
         end if
      else
         print_string(serial_data, "FAIL - Read operation failed")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "FAIL - Write operation failed")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Move to next letter in alphabet
   current_letter = current_letter + 1
   if current_letter > "Z" then
      current_letter = "A"  -- Wrap back to 'A' after 'Z'
   end if

   -- Note: sd_sector_select is automatically incremented by the library after each operation
   print_string(serial_data, "Next sector will be: ")
   print_dword_dec(serial_data, sd_sector_select)
   print_crlf(serial_data)

   -- Small delay between cycles
   _usec_delay(100_000)
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== ALPHABET CYCLING TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #2 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_2

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- EXAMPLE #3: Looped A/B pattern test with CRC error handling
--------------------------------------------------------------------------------
if ENABLE_EXAMPLE_3 then
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC ENABLED")
else
   print_string(serial_data,"EXAMPLE #3: Looped A/B pattern test - CRC DISABLED")
end if
print_crlf(serial_data)

print_string(serial_data, "Starting A/B pattern test...")
print_crlf(serial_data)
if defined(SD_USE_CRC) & (SD_USE_CRC != FALSE) then
   print_string(serial_data, "Testing A/B pattern write/read (CRC enabled)")
else
   print_string(serial_data, "Testing A/B pattern write/read (CRC disabled)")
end if
print_crlf(serial_data)

-- Initialize and start stopwatch for timing
stopwatch_init()
stopwatch_start()

-- Variables for A/B pattern test

-- Variables for looped A/B pattern test
var word cycle_count = 0

print_string(serial_data, "Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " write cycles...")
print_crlf(serial_data)

-- Phase 1: Write A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Write 'A' to sector 23
   for 512 using step1 loop
      sd_sector_buffer[step1] = "A"
   end loop
   sd_retry_operation(23, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Write 'B' to sector 24
   for 512 using step1 loop
      sd_sector_buffer[step1] = "B"
   end loop
   sd_retry_operation(24, 4)  -- Type 4: Write sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Success - no output for each cycle to avoid spam
   else
      print_string(serial_data, "Write B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Write progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

print_string(serial_data, "Write phase complete. Starting ")
print_word_dec(serial_data, TEST_CYCLES)
print_string(serial_data, " read cycles...")
print_crlf(serial_data)

-- Add small delay between write and read phases
_usec_delay(100_000) -- 100ms delay

-- Phase 2: Read back A and B patterns TEST_CYCLES times
for TEST_CYCLES using cycle_count loop
   -- Read 'A' from sector 23
   sd_retry_operation(23, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'A'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "A" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read A cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read A cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Read 'B' from sector 24
   sd_retry_operation(24, 3)  -- Type 3: Read sector buffer
   total_tests = total_tests + 1

   if sd_has_error == FALSE then
      -- Verify all data matches 'B'
      data_match = TRUE
      for 512 using step1 loop
         if sd_sector_buffer[step1] != "B" then
            data_match = FALSE
         end if
      end loop

      if data_match == FALSE then
         print_string(serial_data, "Read B cycle ")
         print_word_dec(serial_data, cycle_count + 1)
         print_string(serial_data, " DATA MISMATCH")
         print_crlf(serial_data)
         data_errors = data_errors + 1
      end if
   else
      print_string(serial_data, "Read B cycle ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, " FAILED")
      print_crlf(serial_data)
      data_errors = data_errors + 1
   end if

   -- Progress indicator every 10 cycles
   if (cycle_count + 1) % 10 == 0 then
      print_string(serial_data, "Read progress: ")
      print_word_dec(serial_data, cycle_count + 1)
      print_string(serial_data, "/")
      print_word_dec(serial_data, TEST_CYCLES)
      print_crlf(serial_data)
   end if
end loop

-- Display test results
print_crlf(serial_data)
print_string(serial_data, "=== LOOPED A/B PATTERN TEST RESULTS ===")
print_crlf(serial_data)
print_string(serial_data, "Test cycles completed: ")
print_word_dec(serial_data, TEST_CYCLES)
print_crlf(serial_data)
print_string(serial_data, "Total operations: ")
print_dword_dec(serial_data, total_tests)
print_crlf(serial_data)
print_string(serial_data, "Data verification errors: ")
print_dword_dec(serial_data, data_errors)
print_crlf(serial_data)

if data_errors == 0 then
   print_string(serial_data, "ALL TESTS PASSED - Data integrity verified!")
else
   print_string(serial_data, "SOME TESTS FAILED - Data integrity issues detected")
end if
print_crlf(serial_data)

-- Stop stopwatch and display timing results
stopwatch_stop()

-- Display timing information
print_string(serial_data, "Example #3 execution time: ")
print_dword_dec(serial_data, stopwatch)
print_string(serial_data, " ms")
print_crlf(serial_data)
print_string(serial_data, "Instruction cycles: ")
print_dword_dec(serial_data, stopwatch_cycles)
print_crlf(serial_data)

-- Calculate and display average time per cycle
var dword average_time_per_cycle = 0
var dword average_cycles_per_cycle = 0

-- Calculate average time per cycle (total time / number of cycles)
average_time_per_cycle = stopwatch / TEST_CYCLES
print_string(serial_data, "Average time per cycle: ")
print_dword_dec(serial_data, average_time_per_cycle)
print_string(serial_data, " ms")
print_crlf(serial_data)

-- Calculate average instruction cycles per cycle
average_cycles_per_cycle = stopwatch_cycles / TEST_CYCLES
print_string(serial_data, "Average instruction cycles per cycle: ")
print_dword_dec(serial_data, average_cycles_per_cycle)
print_crlf(serial_data)

-- Calculate bytes per second
var dword total_bytes_transferred = 0
var dword bytes_per_second = 0
var dword total_seconds = 0

-- Calculate total bytes transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 512 bytes
total_bytes_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
total_bytes_transferred = total_bytes_transferred * 512  -- multiply by bytes_per_operation
total_seconds = stopwatch / 1000  -- Convert milliseconds to seconds
bytes_per_second = total_bytes_transferred / total_seconds

print_string(serial_data, "Total bytes transferred: ")
print_dword_dec(serial_data, total_bytes_transferred)
print_crlf(serial_data)
print_string(serial_data, "Data transfer rate: ")
print_dword_dec(serial_data, bytes_per_second)
print_string(serial_data, " bytes/second")
print_crlf(serial_data)

-- Calculate sectors per second
var dword total_sectors_transferred = 0
var dword sectors_per_second = 0

-- Calculate total sectors transferred (4 operations per cycle: write A, write B, read A, read B)
-- Each operation transfers 1 sector (512 bytes)
total_sectors_transferred = TEST_CYCLES * 4  -- cycles * operations_per_cycle
sectors_per_second = total_sectors_transferred / total_seconds

print_string(serial_data, "Total sectors transferred: ")
print_dword_dec(serial_data, total_sectors_transferred)
print_crlf(serial_data)
print_string(serial_data, "Sector transfer rate: ")
print_dword_dec(serial_data, sectors_per_second)
print_string(serial_data, " sectors/second")
print_crlf(serial_data)

end if  -- ENABLE_EXAMPLE_3

sd_seperator()                                  -- seperate the examples with "----"
_usec_delay(500_000)                         -- a small delay

--------------------------------------------------------------------------------
-- Final Statistics
--------------------------------------------------------------------------------
sd_print_enhanced_statistics()

print_crlf(serial_hw_data)
print_string(serial_hw_data, "##DONE##")
print_crlf(serial_hw_data)
print_string(serial_hw_data, "#")

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_set_idle - JALlib Procedures Help

sd_set_idle JALLIB PROCEDURE

Signature

procedure sd_set_idle() is

Description

Set SD card to idle state
Stops any ongoing operations and resets card to idle

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_start_read - JALlib Procedures Help

sd_start_read JALLIB PROCEDURE

Signature

procedure sd_start_read(dword in address) is

Description

Start reading multiple blocks from SD card
Initiates multi-block read operation at specified sector

Include

To use this procedure, include the library:

include sd_card

Parameters

  • address - dword in - Sector number to start reading from

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_start_write - JALlib Procedures Help

sd_start_write JALLIB PROCEDURE

Signature

procedure sd_start_write(dword in address) is

Description

Start writing multiple blocks to SD card
Initiates multi-block write operation at specified sector

Include

To use this procedure, include the library:

include sd_card

Parameters

  • address - dword in - Sector number to start writing to

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_stop_read - JALlib Procedures Help

sd_stop_read JALLIB PROCEDURE

Signature

procedure sd_stop_read() is

Description

Stop multi-block read operation
Ends read session and returns SD card to idle state

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_stop_write - JALlib Procedures Help

sd_stop_write JALLIB PROCEDURE

Signature

procedure sd_stop_write() is

Description

Stop multi-block write operation
Ends write session and returns SD card to idle state

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_toggle - JALlib Procedures Help

sd_toggle JALLIB PROCEDURE

Signature

procedure sd_toggle() is

Description

Toggle SD card chip select (disable then enable)
Performs a reset of the chip select line

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_write_pulse - JALlib Procedures Help

sd_write_pulse JALLIB PROCEDURE

Signature

procedure sd_write_pulse(byte in count1) is

Description

Write zero bytes to SD card (OBSOLETE)
Writes pairs of zero bytes to advance write position

Include

To use this procedure, include the library:

include sd_card

Parameters

  • count1 - byte in - Number of byte pairs to write (writes count1 * 2 bytes)

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_write_pulse_byte - JALlib Procedures Help

sd_write_pulse_byte JALLIB PROCEDURE

Signature

procedure sd_write_pulse_byte(word in count1) is

Description

Write zero bytes to SD card
Advances write position by writing specified number of zeros

Include

To use this procedure, include the library:

include sd_card

Parameters

  • count1 - word in - Number of zero bytes to write

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_write_sector - JALlib Procedures Help

sd_write_sector JALLIB PROCEDURE

Signature

procedure sd_write_sector() is

Description

Write one complete 512-byte sector from buffer
Writes entire sector from sd_sector_buffer to current position

Include

To use this procedure, include the library:

include sd_card

Parameters

None

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_write_sector_address - JALlib Procedures Help

sd_write_sector_address JALLIB PROCEDURE

Signature

procedure sd_write_sector_address(dword in address) is

Description

Write single sector at specified address
Convenience function combining start, write, and stop operations

Include

To use this procedure, include the library:

include sd_card

Parameters

  • address - dword in - Sector number to write to

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_write_sector_with_callback - JALlib Procedures Help

sd_write_sector_with_callback JALLIB PROCEDURE

Signature

procedure sd_write_sector_with_callback(word in chunk_size) is

Description

Write sector in chunks using callback function
Allows user-provided callback to supply data as it's written

Include

To use this procedure, include the library:

include sd_card

Parameters

  • chunk_size - word in - Number of bytes per callback (must divide evenly into 512)

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sd_write_to_sector_end - JALlib Procedures Help

sd_write_to_sector_end JALLIB PROCEDURE

Signature

procedure sd_write_to_sector_end(byte in input_byte) is

Description

Fill remainder of current sector with specified byte
Pads sector to 512 bytes with repeated byte value

Include

To use this procedure, include the library:

include sd_card

Parameters

  • input_byte - byte in - Byte value to use for padding

Return Value

None

Example

No example found in sample files.

Generated by JALlib CHM Help System | Source: sd_card.jal


sdp600.jal - JALLIB Library Documentation

sdp600.jal JALLIB LIBRARY

Title

sdp600, Sensirion differential pressure sensor with I2C output

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2012, Adapted-by:

Compiler

=2.40

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library works with the Sensirion SDP600 series pressure sensors
Output is value, pressure in Pascal is value/scale, where scale is typically 60.
Range is -500 to 500 Pa.
Nota Bene: these sensors have 3V3 supply and data!

Declare this in main program:

i2c setup
const word _i2c_bus_speed = 1 ; * 100kHz
const bit _i2c_level = true ; i2c levels (not SMB)
include i2c_hardware
i2c_initialize()
include sdp600

Sources

http://www.sensirion.com/en/pdf/product_information/Datasheet_SDP600series_differential_pressure_sensor.pdf

Constants and Variables

sdp600_addr - const byte = 0b1000_0000 -- add 1 when reading, add zero when writing
add 1 when reading, add zero when writing

Routines

  • sdp600_read_press_pa - Function returns sword
  • sdp600_read_press_raw - Function returns sword
  • sdp600_soft_reset - Procedure


sdp600_read_press_pa - JALlib Procedures Help

sdp600_read_press_pa JALLIB FUNCTION

Signature

function sdp600_read_press_pa() return sword is

Description

initiate pressure measurement and read data
returns pressure in pascal as sword
does not check CRC

Include

To use this procedure, include the library:

include sdp600

Parameters

None

Return Value

None

Example

From sample file: 18f452_pressure.jal

-- Title: 18f452_pressure, sample program for sdp600 Sensirion pressure sensor
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2012
-- Adapted-by:
-- Compiler: =2.40
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: usage of SDP600 I2C pressure sensor library
-- Has both serial and LCD output
--
-- This file has been generated by hand (manually maintained)
--

-- include chip
include 18f452					   -- target picmicro, running at 3V3
pragma target clock 10_000_000	   -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS			   -- HS crystal or resonator
pragma target WDT  CONTROL		   -- no watchdog
pragma target LVP  enabled 		   -- allow Low Voltage Programming

-- LCD & 4x4 keyboard
var bit lcd_sterm_pin is pin_c2		-- Sterm LCD & keyboard
var bit lcd_sterm_pin_dir is pin_c2_direction
const LCD_ROWS = 4
const LCD_CHARS = 20
include lcd_sterm_master

-- i2c protocol for sensor
const word _i2c_bus_speed = 1 ; 100 kHz
const bit _i2c_level = true	  ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl			 is pin_scl
alias i2c_scl_direction	 is pin_scl_direction
alias i2c_sda			 is pin_sda
alias i2c_sda_direction	 is pin_sda_direction
--
include i2c_software
i2c_initialize()

const down  = 0
const green = 1
const red   = 2

var bit led     is pin_c5		   -- red and green LED
var bit led_dir is pin_c5_direction
led_dir = output                 -- so green at startup
led = high

procedure leds(byte in x) is     -- two leds in series with two diodes betw +3V3 and GND
   if x == down then             -- 2*1.7V+2*0.6V = 4.6V Vf, they will not light up
      led_dir  = input           -- PIC pin is tied to the middle, via 100 Ohm resistor
   elsif x == red then           -- so HIGH will light lower green LED
      led_dir  = output          -- LOW will light upper RED led
      led      = low             -- pin_direction = input will light no LEDs.
   elsif x == green then
      led_dir  = output
       led     = high
   end if
end procedure

include delay

-- serial output too
const serial_hw_baudrate  = 57600
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

include print           -- print to serial port and LCD
include format          -- format numbers on LCD and serial port

var sword raw_press     -- raw data from sensor
var sword pressure      -- in Pascal

var byte loop_counter
var bit toggle

include sdp600

procedure display() is

   lcd_cursor_position(0,0)   -- LINE 1
   lcd = "r" lcd = "a" lcd = "w" lcd = ":"
   format_sword_dec_length(lcd, raw_press, true, 7, 0)
   lcd = " "                        --
   lcd = " "                        --

   lcd_cursor_position(1,0)  -- LINE 2
   lcd = "p" lcd = "r" lcd = "e" lcd = "s" lcd = "s" lcd = "u" lcd = "r" lcd = "e" lcd = ":"
   print_sword_dec(lcd, pressure)
   lcd = " "                        --

   lcd_cursor_position(2,0)   -- LINE 3
   print_byte_dec(lcd, loop_counter)         -- fan
   lcd = " "                        --
   lcd = " "                        --

   lcd_cursor_position(3,0)   -- LINE 4

end procedure

-- start of main program

for 5 loop
   leds(red)
   delay_100ms(2)
   leds(green)
   delay_100ms(2)
   lcd_clear_screen()  -- reset Sterm
end loop

--                   12345678901234567890
const byte str7[] = "SDP600 pressure test"

lcd_cursor_position(0,0)    -- first line on LCD
print_string(lcd, str7)

print_string(serial_hw_data, str7)
serial_hw_data = ASCII_LF
serial_hw_data = ASCII_CR
serial_hw_data = ASCII_LF           -- empty line
serial_hw_data = ASCII_CR

delay_1s(3)

lcd_clear_screen()  -- reset Sterm

forever loop -- MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM  M A I N   L O O P   MMMMMMMMMMMMMMMMMMMMM

   display

   raw_press = sdp600_read_press_raw()
   pressure = sdp600_read_press_pa()

   delay_100ms(2)    -- for visibility of display

   loop_counter = loop_counter + 1

   if loop_counter % 10 == 0 then       -- every 2 seconds
       serial_hw_data = "r" serial_hw_data = "a" serial_hw_data = "w" serial_hw_data = ":"
       format_sword_dec_length(serial_hw_data, raw_press, true, 7, 0)
       serial_hw_data = " "                        --

       serial_hw_data = "p" serial_hw_data = "r" serial_hw_data = "e"
       serial_hw_data = "s" serial_hw_data = "s" serial_hw_data = "u"
       serial_hw_data = "r" serial_hw_data = "e" serial_hw_data = ":"
       print_sword_dec(serial_hw_data, pressure)
       serial_hw_data = ASCII_LF           -- empty line
       serial_hw_data = ASCII_CR

   end if

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

end loop    -- end of main loop

Generated by JALlib CHM Help System | Source: sdp600.jal


sdp600_read_press_raw - JALlib Procedures Help

sdp600_read_press_raw JALLIB FUNCTION

Signature

function sdp600_read_press_raw() return sword is

Description

initiate pressure measurement and read data
returns raw data as sword
raw data is pressure * scale
does not check CRC

Include

To use this procedure, include the library:

include sdp600

Parameters

None

Return Value

None

Example

From sample file: 18f452_pressure.jal

-- Title: 18f452_pressure, sample program for sdp600 Sensirion pressure sensor
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2012
-- Adapted-by:
-- Compiler: =2.40
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: usage of SDP600 I2C pressure sensor library
-- Has both serial and LCD output
--
-- This file has been generated by hand (manually maintained)
--

-- include chip
include 18f452					   -- target picmicro, running at 3V3
pragma target clock 10_000_000	   -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS			   -- HS crystal or resonator
pragma target WDT  CONTROL		   -- no watchdog
pragma target LVP  enabled 		   -- allow Low Voltage Programming

-- LCD & 4x4 keyboard
var bit lcd_sterm_pin is pin_c2		-- Sterm LCD & keyboard
var bit lcd_sterm_pin_dir is pin_c2_direction
const LCD_ROWS = 4
const LCD_CHARS = 20
include lcd_sterm_master

-- i2c protocol for sensor
const word _i2c_bus_speed = 1 ; 100 kHz
const bit _i2c_level = true	  ; i2c levels (not SMB)
-- I2C PINS
alias i2c_scl			 is pin_scl
alias i2c_scl_direction	 is pin_scl_direction
alias i2c_sda			 is pin_sda
alias i2c_sda_direction	 is pin_sda_direction
--
include i2c_software
i2c_initialize()

const down  = 0
const green = 1
const red   = 2

var bit led     is pin_c5		   -- red and green LED
var bit led_dir is pin_c5_direction
led_dir = output                 -- so green at startup
led = high

procedure leds(byte in x) is     -- two leds in series with two diodes betw +3V3 and GND
   if x == down then             -- 2*1.7V+2*0.6V = 4.6V Vf, they will not light up
      led_dir  = input           -- PIC pin is tied to the middle, via 100 Ohm resistor
   elsif x == red then           -- so HIGH will light lower green LED
      led_dir  = output          -- LOW will light upper RED led
      led      = low             -- pin_direction = input will light no LEDs.
   elsif x == green then
      led_dir  = output
       led     = high
   end if
end procedure

include delay

-- serial output too
const serial_hw_baudrate  = 57600
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

include print           -- print to serial port and LCD
include format          -- format numbers on LCD and serial port

var sword raw_press     -- raw data from sensor
var sword pressure      -- in Pascal

var byte loop_counter
var bit toggle

include sdp600

procedure display() is

   lcd_cursor_position(0,0)   -- LINE 1
   lcd = "r" lcd = "a" lcd = "w" lcd = ":"
   format_sword_dec_length(lcd, raw_press, true, 7, 0)
   lcd = " "                        --
   lcd = " "                        --

   lcd_cursor_position(1,0)  -- LINE 2
   lcd = "p" lcd = "r" lcd = "e" lcd = "s" lcd = "s" lcd = "u" lcd = "r" lcd = "e" lcd = ":"
   print_sword_dec(lcd, pressure)
   lcd = " "                        --

   lcd_cursor_position(2,0)   -- LINE 3
   print_byte_dec(lcd, loop_counter)         -- fan
   lcd = " "                        --
   lcd = " "                        --

   lcd_cursor_position(3,0)   -- LINE 4

end procedure

-- start of main program

for 5 loop
   leds(red)
   delay_100ms(2)
   leds(green)
   delay_100ms(2)
   lcd_clear_screen()  -- reset Sterm
end loop

--                   12345678901234567890
const byte str7[] = "SDP600 pressure test"

lcd_cursor_position(0,0)    -- first line on LCD
print_string(lcd, str7)

print_string(serial_hw_data, str7)
serial_hw_data = ASCII_LF
serial_hw_data = ASCII_CR
serial_hw_data = ASCII_LF           -- empty line
serial_hw_data = ASCII_CR

delay_1s(3)

lcd_clear_screen()  -- reset Sterm

forever loop -- MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM  M A I N   L O O P   MMMMMMMMMMMMMMMMMMMMM

   display

   raw_press = sdp600_read_press_raw()
   pressure = sdp600_read_press_pa()

   delay_100ms(2)    -- for visibility of display

   loop_counter = loop_counter + 1

   if loop_counter % 10 == 0 then       -- every 2 seconds
       serial_hw_data = "r" serial_hw_data = "a" serial_hw_data = "w" serial_hw_data = ":"
       format_sword_dec_length(serial_hw_data, raw_press, true, 7, 0)
       serial_hw_data = " "                        --

       serial_hw_data = "p" serial_hw_data = "r" serial_hw_data = "e"
       serial_hw_data = "s" serial_hw_data = "s" serial_hw_data = "u"
       serial_hw_data = "r" serial_hw_data = "e" serial_hw_data = ":"
       print_sword_dec(serial_hw_data, pressure)
       serial_hw_data = ASCII_LF           -- empty line
       serial_hw_data = ASCII_CR

   end if

   toggle = ! toggle
   if toggle then
      leds(green)
   else
      leds(down)
   end if

end loop    -- end of main loop

Generated by JALlib CHM Help System | Source: sdp600.jal


send_command - JALlib Procedures Help

send_command JALLIB PROCEDURE

Signature

procedure send_command(byte in command,dword in data, byte out response) is

Description

Send a command to the SD card
Transmits SD command with parameters and receives R1 response

Include

To use this procedure, include the library:

include sd_card

Parameters

  • command - byte in - SD command number (0-63)
  • data - dword in - 32-bit command argument/parameter
  • response - byte out - Returns R1 response byte from SD card

Return Value

None

Example

From sample file: 18f452_servo_rc_master_dedicated_master_i2c.jal

-- Title: Sample master to control a dedicated RC servo controller PIC
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4m
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample controls an external PIC that acts as a slave device
--              and is a dedicated PIC for servo movements. Slave PIC can support
--              24 servos that are the type used in radio control (RC)
--
-- This file has been generated by hand (manually maintained)
--
-- Notes:
-- See other servo samples before using this one
--
-- Master clock/oscillator should be equal or less then slave clock/osc
-- otherwise you may need to limit I2C bus speed.
--
-- The external pic should be written with a sample such as
-- 18fxxx_servo_rc_master_dedicated_slave_i2c.jal
--
-- Sources:
-- http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html
--

-- include chip
include 18f452                     -- target picmicro
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS              -- HS crystal or resonator
pragma target WDT  CONTROL        -- no watchdog
pragma target LVP  enabled         -- allow Low Voltage Programming

enable_digital_io()                -- make all pins digital I/O
-- Setup I2C
--
-- I2C pin definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 4 -- 400kHz
const bit _i2c_level = true   -- i2c levels (not SMB)
include i2c_software          -- include i2c software lib
i2c_initialize()              -- initialize i2c lib

-- Setup the dedicated pic servo library, to control an external servo pic.
--
-- specify weather to wait for slave device to be ready before continuing
-- main program. If set to false you must check the ready bit via ready function,
-- or delay 1ms between commands.
const byte SERVO_RC_MASTER_DEDICATED_WAIT = TRUE
--
-- include the dedicated servo library.
-- slave/dedicated pic runs servo_rc_master library.
include servo_rc_master_dedicated

-- main program here
var byte servo_ic_address = 0x6E -- the dedicate/external servo pic i2c address

-- set min/max movement. servo number cannot be selected, changing min/max
-- movement affects all servo's. if you do not sendA these 2 commands,
-- the default is min 50, max 250 (500us to 2.50ms pulses)
servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MIN, 50, 0)
servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MAX, 250, 0)

forever loop
   -- move pic 1 & 17 to center position
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 17)
   _usec_delay(1_000_000)

   -- move pic 1 & 17 to one side
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 255, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 255, 17)
   _usec_delay(1_000_000)

   -- move pic 1 & 17 to center position
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 17)
   _usec_delay(1_000_000)

   -- move pic 1 & 17 to other side
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 0, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 0, 17)
   _usec_delay(1_000_000)

   -- reverse direction of servo 1
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_REVERSE, TRUE, 1)

   -- turn off servo 17
   ;servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_ON_OFF, OFF, 17)
end loop

Generated by JALlib CHM Help System | Source: sd_card.jal


serial_hardware2.jal - JALLIB Library Documentation

serial_hardware2.jal JALLIB LIBRARY

Title

USART2 hardware control

Author

Stef Mientki, Copyright (c) 2002..2020, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

USART2 hardware control.
Routines for sending and receiving through the second [E]USART2

Notes

- See also the notes in serial_hardware library.
- When the physical locations of pin_TX and pin_RX are configurable for
a specific PIC, the device file will probably contain names like
pin_TX2_RC2 and pin_RX2_RC1 and another pair with other pin suffixes.
Depending for which pair of pins the USART is configured aliases
without suffixes have to be specified, like:
alias pin_TX2 is pin_TX2_RC2
alias pin_RX2 is pin_RX2_RC1
alias pin_TX2_direction is pin_TX2_RC2_direction
alias pin_RX2_direction is pin_RX2_RC1_direction

Aliases to get things working for PIC with different type of usarts.

Constants and Variables

BAUDCON2_BRG16 - var bit = TRUE

Routines

  • _serial_hw2_read - Function returns bit
  • serial_hw2_data'get - Function returns byte
  • serial_hw2_data'put - Procedure
  • serial_hw2_data_available - Function returns bit
  • serial_hw2_data_raw'get - Function returns byte
  • serial_hw2_data_raw'put - Procedure
  • serial_hw2_data_ready - Function returns bit
  • serial_hw2_disable - Procedure
  • serial_hw2_enable - Procedure
  • serial_hw2_init - Procedure
  • serial_hw2_read - Function returns bit
  • serial_hw2_write - Procedure
  • serial_hw2_write_word - Procedure


serial_hardware3.jal - JALLIB Library Documentation

serial_hardware3.jal JALLIB LIBRARY

Title

UART hardware control for USART 3

Author

Rob Jansen, Copyright (c) 2021..2021 all rights reserved., Adapted-by:

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

USART3 hardware control.
Routines for sending and receiving through the second [E]USART3.

Notes

- See also the notes in serial_hardware library.
Tested for baudrates from 1200 baud to 115200 baud.
- When the physical locations of pin_TX and pin_RX are configurable for
a specific PIC, the device file will probably contain names like
pin_TX2_RC3 and pin_RX3_RC1 and another pair with other pin suffixes.
Depending for which pair of pins the USART is configured aliases
without suffixes have to be specified, like:
alias pin_TX3_direction is pin_TX3_RC2_direction
alias pin_RX3_direction is pin_RX3_RC1_direction

Sources

Based on the serial_hardware2.jal library by Stef Mientki.
-----------------------------------------------------------------------------

Aliases to get things working for future PIC with different type of usarts.
Aliases to support newer USART types.

Routines

  • _serial_hw3_read - Function returns bit
  • serial_hw3_data'get - Function returns byte
  • serial_hw3_data'put - Procedure
  • serial_hw3_data_available - Function returns bit
  • serial_hw3_data_raw'get - Function returns byte
  • serial_hw3_data_raw'put - Procedure
  • serial_hw3_data_ready - Function returns bit
  • serial_hw3_disable - Procedure
  • serial_hw3_enable - Procedure
  • serial_hw3_init - Procedure
  • serial_hw3_read - Function returns bit
  • serial_hw3_write - Procedure
  • serial_hw3_write_word - Procedure


serial_hardware.jal - JALLIB Library Documentation

serial_hardware.jal JALLIB LIBRARY

Title

USART hardware control

Author

Stef Mientki, Copyright (c) 2002..2025, all rights reserved., Adapted-by: Sebastien Lelong, Rob Hamerling, Rob Jansen

Compiler

2.5r9

Licenses

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 asynchronous and synchronous 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.
This library supports old and new USART types.
TODO: should this be configurable ?
Transmission parameters are 8 databits, 1 stopbit, no parity, no handshake.

Notes

- Pin selection is automatic: pin_TX and pin_RX.
- For PICs using the newer USART types, make sure to remap the USART
pins to their default in the main program to enable the USART pins.
- Pin direction setting is taken care of by this library.
- When the physical locations of pin_TX and pin_RX are configurable for
a specific PIC, the device file will probably contain names like
pin_TX_RB2 and pin_RX_RB1 and another pair with other pin suffixes.
Depending for which pair of pins the USART is configured aliases
without suffixes have to be specified, like:
alias pin_TX is pin_TX_RB2
alias pin_RX is pin_RX_RB1
alias pin_TX_direction is pin_TX_RB2_direction
alias pin_RX_direction is pin_RX_RB1_direction

Aliases to get things working for PIC with different type of usarts.

Constants and Variables

BAUDCON_BRG16 - var bit = TRUE

Routines

  • _serial_hw_read - Function returns bit
  • serial_hw_data'get - Function returns byte
  • serial_hw_data'put - Procedure
  • serial_hw_data_available - Function returns bit
  • serial_hw_data_raw'get - Function returns byte
  • serial_hw_data_raw'put - Procedure
  • serial_hw_data_ready - Function returns bit
  • serial_hw_disable - Procedure
  • serial_hw_enable - Procedure
  • serial_hw_init - Procedure
  • serial_hw_read - Function returns bit
  • serial_hw_write - Procedure
  • serial_hw_write_word - Procedure


serial_hw2_data_available - JALlib Procedures Help

serial_hw2_data_available JALLIB FUNCTION

Signature

function serial_hw2_data_available() return bit is

Description

generic function to check if a byte is received

Include

To use this procedure, include the library:

include serial_hw2_int_cts

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f15325_bluetooth_hc05_master.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Bluetooth HC-05 module in master mode.
--
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demonstrates the features of the Bluetooth HC-05 module in master mode.
--              Next to that this sample program offers 2 different functionalities
--              which requires that it needs to be re-compiled.
--              1) The first feature is setting up the HC-05 in master mode so it will be
--                 able to connect with HC-06 slave. The constant BLUETOOTH_HC05_SETUP
--                 must be set to compile this sample program for this featre. If not
--                 set it will be compiled for the second (following) feature.
--                 Once the setup is done the HC-05 keeps that setting until it is
--                 reprogrammed again.
--              2) This feature can be programmed after 1) has been one which is exchanging
--                 data between the HC-05 and HC-06. Data received from the HC-06 will be
--                 sent to USART2 and data received via USART2 will be sent to th HC-06.
--                 Also see the notes what is required from a hardware point of view.
--
-- Sources:     *) GHC-03/05 Embedded Bluetooth Serial Communication Module AT command set
--                 April, 2011
--              *) EGBT-045MS-046S Hardware Manual & AT Commands Reference Manual
--                 Rev. 1r0
--              *) http://www.martyncurrey.com/arduino-with-hc-05-bluetooth-module-at-mode/
--
-- Notes:       The HC-05 module uses a serial interface so at least one of the
--              JAL serial hardware libraries must be included by the main program.
--
--              This sample programs assumes that a slave Bluetooth device is
--              available with the application with the 2 switches and the 2 LEDs
--              as given in sample program '16f1823_bluetooth_hc06.jal'.
--
--              This sample program also contains some extra options to show status
--              information of the HC-05 module. This information is not needed for the
--              the set-up (feature 1) but can be used for debugging purposes. This
--              can be enabled by defining the constant BLUETOOTH_HC05_EXTRA.
--
--              PIC USART connections for this PIC (14 pin DIP):
--              *) TX 1: pin 5  of the USART1 of the PIC to the RX pin of the Module.
--              *) RX 1: pin 6  of the USART1 of the PIC to the TX pin of the Module.
--              *) TX 2: pin 9  of the USART2 of the PIC to the pin 11 of the MAX232.
--              *) RX 2: pin 10 of the USART2 of the PIC to the pin 12 of the MAX232.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the Module
alias pin_RX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP
alias pin_TX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_C0_direction  -- Pin 10 for 14 pin DIP
alias pin_TX2_direction is pin_C1_direction  -- Pin 9  for 14 pin DIP.

-- Pin to power up the module (active LOW).
alias Power_pin is pin_A4                   -- Active LOW
pin_A4_direction = output                   -- Pin 3 for 14 pin DIP.

-- Pin to enable the full AT command mode..
alias Enable_pin is pin_C2                  -- Active HIGH
pin_C2_direction = output                   -- Pin 8 for 14 pin DIP.

-- ------------------------- Constant declarations -----------------------------

-- When we compile this program with the following constant it will set-up the
-- HC-05 as master to communicate with a Bluetooth slave device like an HC-06.
-- If not defined and compiling this program, this program is just an
-- application that sends received data back assuming that the set-up has
-- been done (since the set-up that is done is stored in the HC-05).
const BLUETOOTH_HC05_SETUP = TRUE

-- The following constant is used to include some extra information that will
-- be printed for testing purposes but which is not required for the set-up.
-- const BLUETOOTH_HC05_EXTRA = TRUE

-- Baudrate definitions. Module default is 38400 baud but after set up it is
-- 9600 baud since that is what we use in the set-up for communicating with
-- the HC-06.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Baudrate of the HC-05 module in full AT mode (enable pin is high).
   const serial_hw_baudrate = 38400
   Enable_pin = HIGH
else
   -- Baudrate of the HC-05 module for communcation with the HC-06 (enable pin is low).
   const serial_hw_baudrate = 9600
   Enable_pin = LOW
end if

-- USART speed for the terminal.
const serial_hw2_baudrate = 115200

-- Optional. Wait at most 30 seconds for a response from the module. This very long
-- timeout is needed for the inquiry to find the available bluetooth devices.
const dword BLUETOOTH_HC05_SHORT_READ_TIMEOUT = 30_000  -- 3 seconds, see library.
const dword BLUETOOTH_HC05_LONG_READ_TIMEOUT = 200_000 -- 20 seconds, see library.

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- module so that this USART is used for communication with the module.
-- For the HC-05 library  must use the interrupt based serial routines to prevent
-- data loss when data is received. Adjust the buffer size to limit timing
-- problems or to deal with baudrate differences.
const SERIAL_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL_DELTA      = 0
include serial_hw_int_cts
include bluetooth_hc05       -- It will use the above included serial interface.

-- Some constants for reprogramming the HC-05. Change to your needs. The password and
-- the baudrate must be the same as the password and the bauddrate of the HC-06 module
-- that we want to connect with.
const dword DEVICE_CLASS      = 0x0000_1F00 -- Uncategorized, for testing purposes.
const byte  DEVICE_PASSWORD[] = "1111" -- Default is "1234"
const byte  DEVICE_NAME[]     = "My HC-05"
const byte  DEVICE_BAUDRATE   = BLUETOOTH_HC05_BAUDRATE_9600 -- This is the default.

-- Name of the device we want to connect with.
const byte REMOTE_DEVICE_NAME[] = "My HC-06"

-- Some Bluetooth addresses for testing.This was the address of my HC-06 module.
-- Change to the address of your remote device.
const word  REMOTE_ADDRESS_NAP = 0x98DA
const byte  REMOTE_ADDRESS_UAP = 0x60
const dword REMOTE_ADDRESS_LAP = 0x00C0B0

-- Terminal data goes via the second USART interface. Adjust the buffer size to
-- limit timing problems or to deal with baudrate differences.
const SERIAL2_XMTBUFSIZE = 10 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 50 -- size of receive buffer
const SERIAL2_DELTA      = 0
include serial_hw2_int_cts
include PPS
include print
include strings

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
RC1PPS   = PPS_TX2       -- TX2 re-assigned to C1  (default)
RX2DTPPS = PPS_RC0       -- C0  re-assigned to RX2 (default)
pps_control_lock(TRUE)

-- ------------------------- Variable declarations -----------------------------

var dword address_lap
var word address_nap
var byte address_uap
var byte inquire_access_mode
var word maximum_devices
var byte timeout
var byte value

-- ------------------------- Procedures ----------------------------------------

-- Wait for 3 seconds.
procedure wait_some_time() is

   _usec_delay(3_000_000)

end procedure

-- Print an ok message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_ok_message() is
   print_string(serial_hw2_data,"Succes!\r\n")
end procedure

-- Print an error message. We use this procedure to limit the amount of rom
-- space that is needed when using dedicated messages.
procedure print_error_message() is
   print_string(serial_hw2_data,"Failed!\r\n")
end procedure

-- Print the contents of the bluetooth receive buffer including CR + LF.
procedure print_receive_buffer() is

   var byte index

   for bluetooth_hc05_bytes_received using index loop
      serial_hw2_data = bluetooth_hc05_receive_buffer[index]
   end loop

   print_crlf(serial_hw2_data)

end procedure

-- Reset the HC-05 module and print the status of the reset. We will
-- also wait some time after reset.
procedure reset_hc05() is

   print_string(serial_hw2_data,"Reset module: ")
   if bluetooth_hc05_reset() then
      print_ok_message()
   else
      print_error_message()
   end if
   -- Always give reset some time.
   wait_some_time()

end procedure

-- Print the given bluetooth address in format NAP:UAP:LAP
procedure print_bluetooth_address(word in nap, byte in uap, dword in lap) is

   var byte lap_byte[3] at lap

   print_string(serial_hw2_data," (NAP:UAP:LAP): ")
   print_word_hex(serial_hw2_data, nap)
   print_string(serial_hw2_data,":")
   print_byte_hex(serial_hw2_data, uap)
   print_string(serial_hw2_data,":")
   -- Only print 24 bits of the lap.
   print_byte_hex(serial_hw2_data, lap_byte[2])
   print_byte_hex(serial_hw2_data, lap_byte[1])
   print_byte_hex(serial_hw2_data, lap_byte[0])
   print_crlf(serial_hw2_data)

end procedure

-- Print the device name of the HC-05 module
procedure print_hc05_device_name() is

   print_string(serial_hw2_data,"Get moduled device name: ")
   if bluetooth_hc05_get_device_name() then
      print_receive_buffer()
   else
      print_error_message()
   end if

end procedure

-- Print the device class of the HC-05 module. It is only 24 bits
procedure print_hc05_device_class() is

   var dword class
   var byte class_byte[3] at class

   print_string(serial_hw2_data,"Get module device class: ")
   if bluetooth_hc05_get_device_class(class) then
      print_byte_hex(serial_hw2_data,class_byte[2])
      print_byte_hex(serial_hw2_data,class_byte[1])
      print_byte_hex(serial_hw2_data,class_byte[0])
      print_crlf(serial_hw2_data)
   else
      print_error_message()
   end if

end procedure

-- This procedure does the set-up of the HC-05 module as described
-- for feature 1). It will also show the status of some settings,
-- for the purpose of testing the library.
procedure setup_hc_05_module() is

   if defined(BLUETOOTH_HC05_EXTRA) then
     -- Let's see if the module is available for programming.
      print_string(serial_hw2_data,"Check if module is available: ")
      if bluetooth_hc05_available() then
         print_ok_message()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module version number.
      print_string(serial_hw2_data,"Get module firmware version: ")
      if bluetooth_hc05_get_firmware_version() then
        print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the Module Bluetooth address.
      print_string(serial_hw2_data,"Get module bluetooth address: ")
      if bluetooth_hc05_get_bluetooth_address(address_nap, address_uap, address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device name of the module.
      print_hc05_device_name()
      print_string(serial_hw2_data,"Set device name: ")
      -- Now change it and print it again.
      if bluetooth_hc05_set_device_name(DEVICE_NAME) then
         print_ok_message()
      else
         print_error_message()
      end if
      -- Now get the name again.
      print_hc05_device_name()
   end if

   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the device class of the module.
      print_hc05_device_class()
      -- Now change it and print it again.
      print_string(serial_hw2_data,"Set device class: ")
      if bluetooth_hc05_set_device_class(DEVICE_CLASS) then
         print_ok_message()
      else
        print_error_message()
      end if
      -- Now get it again.
      print_hc05_device_class()
   end if

   -- In my case the restore default did work but did often not
   -- return an OK so I ignore it when this happens.
   print_string(serial_hw2_data,"Restore default setting (may fail): ")
   if bluetooth_hc05_restore_default() then
      print_ok_message()
   else
      print_error_message()
   end if
   wait_some_time()

   -- Device password must be set the same as for the HC-06.
   print_string(serial_hw2_data,"Set device password: ")
   if bluetooth_hc05_set_device_password(DEVICE_PASSWORD) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Show the set password.
      print_string(serial_hw2_data,"Get device password: ")
      if bluetooth_hc05_get_device_password() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Set the baudrate to communicate with the HC-06 must be equal.
   print_string(serial_hw2_data,"Set device baudrate: ")
   if bluetooth_hc05_set_baudrate(BLUETOOTH_HC05_BAUDRATE_9600) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
       -- Show the set baudrate.
      print_string(serial_hw2_data,"Get device baudrate: ")
      if bluetooth_hc05_get_device_baudrate() then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Find the address of the HC-06. First clear all paired devices.
   print_string(serial_hw2_data,"Clear any paired devices: ")
   if bluetooth_hc05_clear_all_paired_devices() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Put the HC-05 in master mode.
   print_string(serial_hw2_data,"Put module in master mode: ")
   if bluetooth_hc05_set_device_role(BLUETOOTH_HC05_ROLE_MASTER) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the role of the module.
      print_string(serial_hw2_data,"Get module mode: ")
      if bluetooth_hc05_get_device_role(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Reset the HC-05, this is sometimes needed after changing roles.
   reset_hc05()

   print_string(serial_hw2_data,"Set connection mode to a specific bluetooth address: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_SPECIFIC) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode of the module
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Note that we use the default of BLUETOOTH_HC05_MAX_INQUIRED_DEVICES which is 5.
   print_string(serial_hw2_data,"Set enquire mode to standard, 5 devices, for 9 * 1.28 seconds: ")
   if bluetooth_hc05_set_inquire_access_mode(BLUETOOTH_HC05_INQUIRY_MODE_STANDARD,5,9) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Now get the inquire mode.
      print_string(serial_hw2_data,"Get enquire mode: ")
      if bluetooth_hc05_get_inquire_access_mode(inquire_access_mode,maximum_devices,timeout) then
         print_byte_dec(serial_hw2_data,inquire_access_mode)
         print_string(serial_hw2_data,",")
         print_word_dec(serial_hw2_data,maximum_devices)
         print_string(serial_hw2_data,",")
         print_byte_dec(serial_hw2_data,timeout)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Intialize the SSP profile. This may return an error when it is already initialized
   -- which is no problem so you can ignore it.
   print_string(serial_hw2_data,"Initialize SSP profile (if not already done, so may fail): ")
   if bluetooth_hc05_initialize_ssp_profile() then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Search for Bluetooth device we want to connect with and obtain the address.
   -- For this function an inquiry command is sent to the device and response may take a
   -- while so set a long wait time. The maximum inquire time was previously set by the
   -- function bluetooth_hc05_set_inquire_access_mode so we have to wait at least longer
   -- than that time before 'OK' is returned by the module.
   print_string(serial_hw2_data,"Find remote device address (this may take some time): ")
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_LONG_READ_TIMEOUT)
   if bluetooth_hc05_get_device_address(REMOTE_DEVICE_NAME, address_nap,
                                        address_uap,address_lap) then
      print_bluetooth_address(address_nap, address_uap, address_lap)
    else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      print_string(serial_hw2_data,"Get remote device name: ")
      -- Now that we have remote device address we can get the name.
      if bluetooth_hc05_get_remote_device_name(address_nap,address_uap,
                                               address_lap) then
         print_receive_buffer()
      else
         print_error_message()
      end if
   end if

   -- Shorten the wait time again, it is not needed to wait that long anymore.
   bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)
   -- We need to pair with the HC-06. This command did not give a response but it still
   -- worked (or was not needed) so we do not check for the result.
   print_string(serial_hw2_data,"Pair modules (may fail): ")
   if bluetooth_hc05_pair_with_device(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if

   -- Now bind to this device.
   print_string(serial_hw2_data,"Set binding address: ")
   if bluetooth_hc05_set_binding_address(address_nap,address_uap,address_lap) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the binding address.
      print_string(serial_hw2_data,"Get binding address: ")
      if bluetooth_hc05_get_binding_address(address_nap,address_uap,address_lap) then
         print_bluetooth_address(address_nap, address_uap, address_lap)
      else
         print_error_message()
      end if
   end if

   -- Set the HC-05 to connect to any device.
   print_string(serial_hw2_data,"Set connection mode set to any device: ")
   if bluetooth_hc05_set_connection_mode(BLUETOOTH_HC05_CONNECTION_MODE_ANY) then
      print_ok_message()
   else
      print_error_message()
   end if
   if defined(BLUETOOTH_HC05_EXTRA) then
      -- Get the connection mode.
      print_string(serial_hw2_data,"Get connection mode: ")
      if bluetooth_hc05_get_connection_mode(value) then
         print_byte_dec(serial_hw2_data, value)
         print_crlf(serial_hw2_data)
      else
         print_error_message()
      end if
   end if

   -- Last but not least, connect to our remote device using its address.
   print_string(serial_hw2_data,"Connect to remote device: ")
   if bluetooth_hc05_connect_to_device(address_nap,address_uap,address_lap)  then
      print_ok_message()
   else
      print_error_message()
   end if
   print_crlf(serial_hw2_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

-- The enable pin is already set earlier. Now we need to power up and wait some time.
Power_pin = LOW -- Active low.
-- Give the HC-05 some time to stabilize and start-up.
wait_some_time()

-- Initialize the serial libraries.
serial_hw_init()   -- Used by Bluetooth Module
serial_hw2_init()  -- Used by the main program.

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the Bluetooth HC-05 Module.\r\n")

-- Initialize the module. This is the same as reset.
print_string(serial_hw2_data,"Initialze module (may fail but is done anyway): ")
if bluetooth_hc05_init() then
   print_ok_message()
else
   print_error_message()
end if
-- Wait some time after reset.
wait_some_time()

-- Set the read timeout to another value. Depends on the module being used.
bluetooth_hc05_set_wait_time(BLUETOOTH_HC05_SHORT_READ_TIMEOUT)

-- Here we make the split in set-up or normal operation.
if defined(BLUETOOTH_HC05_SETUP) then
   -- Feature 1): This is the set-part of this sample program.
   print_string(serial_hw2_data,"This version does the set-up of the HC-05 module.\r\n")

   setup_hc_05_module()

   print_string(serial_hw2_data,"Now recompile this program without BLUETOOTH_HC05_SETUP and reprogram the PIC.\r\n")
   print_string(serial_hw2_data,"After that power off and power on both the HC-05 and HC-06.\r\n")
   print_string(serial_hw2_data,"The LEDs on the HC-06 can be controlled using G or R.\r\n")
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_crlf(serial_hw2_data)

   -- We are done here.
   forever loop
      -- Do nothing.
   end loop

else

   -- Feature 2): Not the set-up mode. We are connected use the HC-06, run the main loop.
   -- This is sending the received data to the USART2 but also controlling the LEDs on
   -- the HC-06 sample board using G or R.
   print_string(serial_hw2_data,"This version communicates with the HC-06 module with the name: ")
   print_string(serial_hw2_data,REMOTE_DEVICE_NAME)
   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Note that the module baudrate is set to 9600 baud.\r\n")
   print_string(serial_hw2_data,"To connect to another device change the constant REMOTE_DEVICE_NAME to the name of your module.\r\n")
   print_crlf(serial_hw2_data)

   forever loop

      -- If data is received from the HC-06 slave send it to USART2.
      if bluetooth_hc05_data_available() then
         serial_hw2_data = bluetooth_hc05_data
      end if

     -- If data was received from USART2 send it to the HC-06 slave via
     -- the HC-05 master Bluetooth module.
     if serial_hw2_data_available() then
        bluetooth_hc05_data = serial_hw2_data
     end if

   end loop

end if

Generated by JALlib CHM Help System | Source: serial_hw2_int_cts.jal


serial_hw2_init - JALlib Procedures Help

serial_hw2_init JALLIB PROCEDURE

Signature

procedure serial_hw2_init() is

Description

Title: Initialize second serial port
Arguments: (none)
Returns: (nothing)

Include

To use this procedure, include the library:

include serial_hw2_int_cts

Parameters

None

Return Value

None

Example

From sample file: 16f19176_esp8266_web_server.jal

-- -----------------------------------------------------------------------------
-- Title: ESP8266 web server sample program.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: Inspired by https://github.com/bportaluri/WiFiEsp
--
-- Description:
-- ------------
-- Start the ESP8266 as a webserver. The Web Page will show the status of one
-- of the input pins after a request has been given by the web browser.
-- The web browser must connect to the given IP address which is obtained from
-- the Access Point.
-- Note that this program uses the HTML to format the data but the nformation
-- could also have been sent using plain text.
-- Make sure you have set the right SSID and password in 'MY_SSID' and
-- 'MY_PASSWORD'.
--
-- Dependencies: -
--
-- Hardware info:
-- --------------
-- Important!. The ESP8266 uses a supply voltage of 3.3 Volt. Make sure that
--             your PIC also runs at that supply voltage or make use of a level
--             shifter for connecting the USART pins from the PIC to the ESP8266.
--             Next to that the connection from the PIC to the PC has to be
--             buffered by an RS232 driver like the MAX232. For the connections
--             of the RS232 connection below a non-twisting cable is assumed
--             between the MAX232 and the PC.
--
-- PIC connections (40 pin DIP):
-- *) TX pin 1 (25) of the USART1 of the PIC to the RX pin of the ESP8266 module.
-- *) RX pin 1 (26) of the USART1 of the PIC to the TX pin of the ESP8266 module.
-- *) TX pin 2 (22) of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX pin 2 (21) of the USART2 of the PIC to the pin 12 of the MAX232.
--
-- Connect the ESP8266 module as follows:
-- *) RST pin to 3.3 V
-- *) EN pin with a resistor of 1 kOhm to the 3.3 V
-- *) GPIO15 pin with a resistor of 1 kOhn to ground
--
-- ------------------------------- Pragmas -------------------------------------
-- Some compiler pragmas for optimizations
pragma warn all no
pragma opt variable_reduce yes

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- allow low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1011

enable_digital_io()

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the ESP8266 Module.
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

alias status_pin is pin_A1                   -- The status of this pin will ...
pin_A1_direction = input                     -- ... be shown on the web page.

-- ------------------------- Constant declarations -----------------------------
const serial_hw2_baudrate  = 115200 -- Default speed for debugging.

-- We need a bigger buffer for the web server. When using a Chrome browser, a
-- HTTP Get request is less than 500 bytes.
const ESP8266_MAX_RECEIVE_BUFFER = 1000

const byte MY_SSID[]     = "Your_ID"
const byte MY_PASSWORD[] = "Your_Password"
const byte MY_PORT[]     = "80" -- Port 80 is used for HTTP TCP requests.

-- -------------------------- Includes go here --- -----------------------------
include serial_hw2_int_cts  -- Debug information via the second RS232 interface
include esp8266
include print
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte connection
var byte character
var bit all_ok

-- ------------------------- Functions and Procedures --------------------------
-- Parse the data in the ESP8266 receive buffer and return true if the
-- given token if found.
function parse_response(byte in token[]) return bit is
   var word buffer_index
   var byte token_index

   -- Start token given, look for start token.
   token_index = 0
   buffer_index = 0
   while (token_index < count(token)) & (buffer_index < esp8266_bytes_received) loop
      if (esp8266_receive_buffer[buffer_index] == token[token_index]) then
         token_index = token_index + 1
      else
         -- No match (yet), try again.
         token_index = 0
      end if
      buffer_index = buffer_index + 1
   end loop
   return (token_index == count(token))
end function

procedure print_receive_buffer() is
   var word index_counter
   for esp8266_bytes_received using index_counter loop
      serial_hw2_data = esp8266_receive_buffer[index_counter]
   end loop
end procedure

-- ------------------------------- Main Program  -------------------------------
_usec_delay(1_000_000) -- Gives ESP module also time to start up.

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

serial_hw2_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample web server program for ESP8266.\n")

-- Initialize the device and connect to the Access Point until succes.
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Initializing ESP8266 module ...")
   if esp8266_init() then
      print_string(serial_hw2_data," succes.\n")
      -- Succes, connect to the Access Point.
      while (esp8266_get_connection_status() != ESP8266_CONNECTED) loop
         print_string(serial_hw2_data,"Connecting to WiFi network ... ")
         if esp8266_connect_to_ap(MY_SSID, MY_PASSWORD) then
            print_string(serial_hw2_data," succes.\n")
            all_ok = TRUE
         else
            print_string(serial_hw2_data," failed.\n")
         end if
      end loop
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Start the webserver with a timeout of 10 minutes (600 seconds).
all_ok = FALSE
while !all_ok loop
   print_string(serial_hw2_data,"Starting TCP server with 10 minute timeout ...")
   all_ok = esp8266_server_start(MY_PORT)
   all_ok = all_ok & esp8266_set_server_timeout("600")
   if all_ok then
      print_string(serial_hw2_data," succes.\n")
   else
      print_string(serial_hw2_data," failed.\n")
   end if
end loop

-- Show the IP address to connect to.
if all_ok & esp8266_get_ip_address() then
   print_string(serial_hw2_data,"Open your browser and browse to IP address ")
   print_receive_buffer()
   print_crlf(serial_hw2_data)
end if

forever loop
   -- Poll the pin and send the data as website when there is a request. Note
   -- that a request is a long message that does not fit in the receive buffer.
   -- We only need to check if valid data was received of which we will
   -- assume it was a request.
   if esp8266_data_available() then
      -- Something was received. Get the data but ingnore the content.
      print_string(serial_hw2_data,"Data received. Processing ... ")
      if esp8266_get_data(connection) then
         -- A HTTP request has the following format:
         -- *) A Request-line
         -- *) Zero or more header (General|Request|Entity) fields followed by CRLF
         -- *) An empty line (i.e., a line with nothing preceding the CRLF)
         --    indicating the end of the header fields
         -- *) Optionally a message-body

         -- Make sure that the request goes to the this connection.
         esp8266_set_connection(connection)

         -- We interpret 2 new-lines as a http request.
         if parse_response("\r\n\r\n") then
            print_string(serial_hw2_data,"succes. Sending response ... ")
            -- Send the response. The connection will be closed after completion
            -- of the response.
            all_ok = esp8266_send_data("HTTP/1.1 200 OK\r\n")
            all_ok = all_ok & esp8266_send_data("Content-Type: text/html\r\n")
            all_ok = all_ok & esp8266_send_data("Connection: close\r\n")
            all_ok = all_ok & esp8266_send_data("\r\n") -- End of request.
            all_ok = all_ok & esp8266_send_data("<!DOCTYPE html>\r\n")
            all_ok = all_ok & esp8266_send_data("<html>\r\n")
            all_ok = all_ok & esp8266_send_data("<h1>Hello World!</h1>\r\n")
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("Input pin A1: ")
            if status_pin then
               all_ok = all_ok & esp8266_send_data("High")
            else
               all_ok = all_ok & esp8266_send_data("Low")
            end if
            all_ok = all_ok & esp8266_send_data("<br>\r\n")
            all_ok = all_ok & esp8266_send_data("</html>\r\n")
            if all_ok then
               print_string(serial_hw2_data,"succes.\r\n")
            else
               print_string(serial_hw2_data,"failed.\r\n")
            end if
         else
            print_string(serial_hw2_data,"no HTTP request.\r\n")
         end if
      else
         print_string(serial_hw2_data,"failed.\r\n")
      end if
      if esp8266_close_connection() then
         print_string(serial_hw2_data,"Connection closed succesfully.\r\n")
      else
         print_string(serial_hw2_data,"Error closing connection.\r\n")
      end if
   end if
end loop

Generated by JALlib CHM Help System | Source: serial_hw2_int_cts.jal


serial_hw2_int_cts.jal - JALLIB Library Documentation

serial_hw2_int_cts.jal JALLIB LIBRARY

Title

serial_hw2_int_cts.jal. Interrupt driven buffered serial interface with flow control.

Author

Rob Hamerling, Copyright (c) 2008..2020, all rights reserved., Adapted-by: Karl "Kiste" Seitz, Rob Jansen

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Serial communications for the second USART:
- receive and transmit data transfer is interrupt driven
- receive and transmit data transfer is buffered (circular buffers)
- provides automatic CTS flow control with spare free space for FiFo buffer
.
This library supports:
- Data format: 8 bits data, 1 start-bit, 1 stop bit
- Acceptable baud rate depends on the oscillator frequency
(see BAUD RATES tables in the datasheet).
- Interrupt bits used: TXIE, RCIE, PEIE and GIE.
.
Available procedures/functions for application programs:
.
- serial_hw2_init() -- initialise communications
.
- serial_send2_byte(byte out <byte>) -- send byte
-- returns the transmitted byte
- serial_hw2_read(byte out <byte>) return bit -- receive byte
-- returns TRUE with data,
-- FALSE when no data available
- serial_hw2_write(byte in <byte>) -- send byte (wait if queue full)
.
- serial_hw2_data = <byte> -- send byte, wait if queue full
.
- serial_hw2_tx_buffer_free() -- get free bytes in transmit buffer
-- returns number of free bytes
.
- <byte> = serial_hw2_data -- receive byte, wait if queue empty
.
Directions for use of this library in application programs (in this sequence):
.
1. Declare the following constants:
.
const serial_hw2_baudrate = 115200 -- line speed must be declared (no default)
.
const bit serial2_overflow_discard = FALSE -- Transmit buffer overflow:
-- FALSE: wait for free space (blocking)
-- TRUE: discard data (non-blocking)
-- This flag may be dynamically changed
-- but must then be declared as 'var bit'
.
-- Receive buffer overflow data is
-- prevented by CTS flow control, provided
-- the sender has flow control enabled.
-- Otherwise data discarded without notification!
.
and an alias:
.
alias serial2_ctsinv is pin_B4 -- Incoming data flow control signal
-- Optional, if no CTS flow control needed
-- no dummy needs to be declared.
.
And optionally you could define one or more of the constants below.
You should do so if you want different values than shown (= defaults).
If not defined, the following values are used:
.
const SERIAL2_XMTBUFSIZE = 32 -- size of transmit buffer
const SERIAL2_RCVBUFSIZE = 64 -- size of receive buffer
const SERIAL2_DELTA = 17 -- spare space receive buffer
-- if possible keep SERIAL2_DELTA = 17!
.
When the physical locations of pin_TX2 and pin_RX2 are configurable for a specific
PIC, the device file will probably contain names like pin_TX2_RC2 and pin_RX2_RC1
and another pair with other pin suffixes.
Depending for which pair of pins the USART is configured aliases
without suffixes have to be specified, like:
alias pin_TX2 is pin_TX2_RC2
alias pin_RX2 is pin_RX2_RC1
alias pin_TX2_direction is pin_TX2_RC2_direction
alias pin_RX2_direction is pin_RX2_RC1_direction
.
2. Include this library.
.
and somewhere before actually using serial communications:
.
3. Prepare pins
pin_B4_direction = OUTPUT -- incoming data flow control

Notes

- pin_TX2 and pin_RX2 are selected automatically
- direction settings of these pins are taken care of by the library
.
4. Call serial_hw2_init() to initialize serial communications.
See serial_hw_int_cts library

Sources

----------------------------------------------------------------------
Setup defaults when no value is specified before:

Constants and Variables

serial2_overflow_discard - const bit = FALSE -- no transmit overflow
no transmit overflow
BAUDCON2_BRG16 - var bit = TRUE

Routines

  • _serial2_receive_interrupt_handler - Procedure
  • _serial2_transmit_interrupt_handler - Procedure
  • serial2_send_byte - Function returns byte
  • serial_hw2_data'get - Function returns byte
  • serial_hw2_data'put - Procedure
  • serial_hw2_data_available - Function returns bit
  • serial_hw2_data_ready - Function returns bit
  • serial_hw2_init - Procedure
  • serial_hw2_read - Function returns bit
  • serial_hw2_tx_buffer_free - Function returns byte
  • serial_hw2_write - Procedure


serial_hw2_read - JALlib Procedures Help

serial_hw2_read JALLIB FUNCTION

Signature

function serial_hw2_read(byte out data) return bit is

Description

Title: Return byte (if any) from circular receive buffer of USART
Arguments: received byte (if any)
Returns: - TRUE when byte returned
- FALSE if no byte available
Notes: Sets CTS high when receive buffer has more than
bytes free space after delivering byte to caller.

Include

To use this procedure, include the library:

include serial_hw2_int_cts

Parameters

  • data - byte out

Return Value

bit - - TRUE when byte returned FALSE if no byte available

Example

From sample file: 18f27j53_pps_rx2tx2.jal

-- Title: Sample showing usage of PPS module for 18F27J53
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Peripheral Pin Select (PPS) peripheral allows to arbitrarily assign
-- functions to remappable pins, labelled as RPn, where "n" is the remappable pin
-- number.
-- This sample uses EUSART2 and assigns TX2 output function to pin_B6 (RP9)
-- and RX2 input function to pin_B7 (RP10)
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: API isn't stable, expect changes
--

include 18f27j53                                   -- device

pragma target clock     48_000_000                 -- oscillator frequency

-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN     DISABLED                   -- PLL via fuse turned off
pragma target OSC       HS_PLL
pragma target WDT       control                    -- watchdog
pragma target IOL1WAY   disabled                   -- Mapping allowed multiple time at runtime

WDTCON_SWDTEN = off                                -- no watchdog
OSCTUNE_PLLEN = on                                 -- PLL via OSCTUNE enabled

_usec_delay(2000)                                  -- PLL needs 2ms before stable

enable_digital_io()

include pps                                        -- library

-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)

-- TX2 is an output function: we assign a function to a RP pin (here RP9)
PPS_MAP_RP9 = PPS_TX2CK2

-- RX2 is an input function: we assign a RP pin the a function register
PPS_MAP_RX2DT2 = RP10

-- PPS configuration is done, we can lock again to apply changes
pps_control_lock(true)

-- ok, now setup serial
const serial_hw2_baudrate = 115_200
-- declare aliases for the remapped RX2 and TX2 pins
alias pin_RX2            is  pin_RP10
alias pin_RX2_direction  is  pin_RP10_direction
alias pin_TX2            is  pin_RP9
alias pin_TX2_direction  is  pin_RP9_direction
include serial_hardware2
serial_hw2_init()

include print                                      -- output library

const byte str1[] = "Hello serial world"           -- define a string
print_string(serial_hw2_data, str1)                -- output string to serial

serial_hw2_write("!")                              -- inform user PIC is ready !

var byte char                                      -- will store received char
var word counter = 10

forever loop

   if (serial_hw2_read(char)) then                 -- char received
      serial_hw2_write(char)                       -- echo it
   end if
   counter = counter - 1;
   if (counter == 0) then
      counter = 50000
      serial_hw2_data = "."
   end if

end loop

Generated by JALlib CHM Help System | Source: serial_hw2_int_cts.jal


serial_hw2_write - JALlib Procedures Help

serial_hw2_write JALLIB PROCEDURE

Signature

procedure serial_hw2_write(byte in data) is

Description

Title: Put a single byte in transmit buffer
Arguments: Data (byte) to transmit
Returns (nothing)
Notes: - This is a variant of serial2_send_byte() compatible with
the procedure in the serial_hardware2 library.
- Spins when byte cannot be put in transmit buffer
(buffer full condition).

Include

To use this procedure, include the library:

include serial_hw2_int_cts

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f27j53_pps_rx2tx2.jal

-- Title: Sample showing usage of PPS module for 18F27J53
-- Author: Sbastien Lelong, Copyright (c) 2011, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Peripheral Pin Select (PPS) peripheral allows to arbitrarily assign
-- functions to remappable pins, labelled as RPn, where "n" is the remappable pin
-- number.
-- This sample uses EUSART2 and assigns TX2 output function to pin_B6 (RP9)
-- and RX2 input function to pin_B7 (RP10)
--
-- This file has been generated by hand (manually maintained)
--
-- Notes: API isn't stable, expect changes
--

include 18f27j53                                   -- device

pragma target clock     48_000_000                 -- oscillator frequency

-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN     DISABLED                   -- PLL via fuse turned off
pragma target OSC       HS_PLL
pragma target WDT       control                    -- watchdog
pragma target IOL1WAY   disabled                   -- Mapping allowed multiple time at runtime

WDTCON_SWDTEN = off                                -- no watchdog
OSCTUNE_PLLEN = on                                 -- PLL via OSCTUNE enabled

_usec_delay(2000)                                  -- PLL needs 2ms before stable

enable_digital_io()

include pps                                        -- library

-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)

-- TX2 is an output function: we assign a function to a RP pin (here RP9)
PPS_MAP_RP9 = PPS_TX2CK2

-- RX2 is an input function: we assign a RP pin the a function register
PPS_MAP_RX2DT2 = RP10

-- PPS configuration is done, we can lock again to apply changes
pps_control_lock(true)

-- ok, now setup serial
const serial_hw2_baudrate = 115_200
-- declare aliases for the remapped RX2 and TX2 pins
alias pin_RX2            is  pin_RP10
alias pin_RX2_direction  is  pin_RP10_direction
alias pin_TX2            is  pin_RP9
alias pin_TX2_direction  is  pin_RP9_direction
include serial_hardware2
serial_hw2_init()

include print                                      -- output library

const byte str1[] = "Hello serial world"           -- define a string
print_string(serial_hw2_data, str1)                -- output string to serial

serial_hw2_write("!")                              -- inform user PIC is ready !

var byte char                                      -- will store received char
var word counter = 10

forever loop

   if (serial_hw2_read(char)) then                 -- char received
      serial_hw2_write(char)                       -- echo it
   end if
   counter = counter - 1;
   if (counter == 0) then
      counter = 50000
      serial_hw2_data = "."
   end if

end loop

Generated by JALlib CHM Help System | Source: serial_hw2_int_cts.jal


serial_hw3_init - JALlib Procedures Help

serial_hw3_init JALLIB PROCEDURE

Signature

procedure serial_hw3_init() is

Description

Title: Initialize third serial port
Arguments: (none)
Returns: (nothing)

Include

To use this procedure, include the library:

include serial_hardware3

Parameters

None

Return Value

None

Example

From sample file: 18f47q43_serial_hardware3.jal

-- -----------------------------------------------------------------------------
-- Title: Serial hardware test program for USART 3.
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: USART test program for the Microchip PIC18F47Q43. The program
--              will write a sequence of '.' to the serial port and will echo
--              any character that is received on the serial port.
--
-- Sources: Based on the serial hardware sample program by Joep Suijs.
--
-- Notes:
--
-- -----------------------------------------------------------------------------
--
include 18f47q43                -- target PICmicro
--
pragma target clock 20_000_000  -- oscillator frequency
--
pragma target OSC      HS       -- crystal or resonator
pragma target CLKOUTEN DISABLED -- no clock output
pragma target WDT      DISABLED -- watchdog
pragma target XINST    DISABLED -- do not use extended instructionset
pragma target BROWNOUT DISABLED -- no brownout reset
pragma target FCMEN    DISABLED -- no clock monitoring
pragma target CSWEN    ENABLED  -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED  -- low voltage programming
pragma target MCLR     EXTERNAL -- external reset
pragma target MVECEN   DISABLED -- Do no use multi vectored interrupts

enable_digital_io()             -- make all pins digital I/O

-- PPS is needed to set the USART pins correctly.
include pps
pps_control_lock(FALSE)
-- Change following lines to match your pcb layout.
RB0PPS  = PPS_TX3   -- TX3 assigned to B0
U3RXPPS = PPS_RB1   -- B1 assigned to RX3
pps_control_lock(TRUE)

const serial_hw3_baudrate = 115200
alias pin_tx3_direction	is pin_B0_direction
alias pin_rx3_direction	is pin_B1_direction
include serial_hardware3
serial_hw3_init()

include print
print_string(serial_hw3_data, "Hello serial hardware 3 world!")

-- let's build our loop
var byte char	-- will store received char
var word counter = 10

forever loop

   -- if there is a char, echo it back.
   if (serial_hw3_read(char)) then
      serial_hw3_write(char)  -- that's the echo...
   end if

   -- code block below prints a dot, every now and then, to signal
   -- the pic is alive
   counter = counter - 1     -- count down
   if (counter == 0) then    -- until zero
      counter = 50000        -- then start over counting from 50000
      serial_hw3_data = "."  -- and output a dot to the serial port
   end if

end loop

Generated by JALlib CHM Help System | Source: serial_hardware3.jal


serial_hw3_int_cts.jal - JALLIB Library Documentation

serial_hw3_int_cts.jal JALLIB LIBRARY

Title

Interrupt driven buffered serial interface for USART3 with flow control.

Author

Rob Jansen Copyright (c) 2021..2021, all rights reserved., Adapted-by:

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Serial communications for the third USART:
- receive and transmit data transfer is interrupt driven
- receive and transmit data transfer is buffered (circular buffers)
- provides automatic CTS flow control with spare free space for FiFo buffer
.
This library supports:
- Data format: 8 bits data, 1 start-bit, 1 stop bit
- Acceptable baud rate depends on the oscillator frequency
(see BAUD RATES tables in the datasheet).
- Interrupt bits used: TXIE, RCIE, PEIE and GIE.
.
Available procedures/functions for application programs:
- serial_hw3_init() -- initialise communications
- serial_send3_byte(byte out <byte>) -- send byte
-- returns the transmitted byte
- serial_hw3_read(byte out <byte>) return bit -- receive byte
-- returns TRUE with data,
-- FALSE when no data available
- serial_hw3_write(byte in <byte>) -- send byte (wait if queue full)
- serial_hw3_data = <byte> -- send byte, wait if queue full
- serial_hw3_tx_buffer_free() -- get free bytes in transmit buffer
-- returns number of free bytes
- <byte> = serial_hw3_data -- receive byte, wait if queue empty
.
Directions for use of this library in application programs (in this sequence):
1. Declare the following constants:
const serial_hw3_baudrate = 115200 -- line speed must be declared (no default)
const bit serial3_overflow_discard = FALSE -- Transmit buffer overflow:
-- -) FALSE: wait for free space (blocking)
-- -) TRUE: discard data (non-blocking)
-- This flag may be dynamically changed
-- but must then be declared as 'var bit'
-- Receive buffer overflow data is
-- prevented by CTS flow control, provided
-- the sender has flow control enabled.
-- Otherwise data discarded without notification!
and an alias:
alias serial3_ctsinv is pin_B4 -- Incoming data flow control signal
-- Optional, if no CTS flow control needed
-- no dummy needs to be declared.
And optionally you could define one or more of the constants below.
You should do so if you want different values than shown (= defaults).
If not defined, the following values are used:
const SERIAL3_XMTBUFSIZE = 32 -- size of transmit buffer
const SERIAL3_RCVBUFSIZE = 64 -- size of receive buffer
const SERIAL3_DELTA = 17 -- spare space receive buffer
-- if possible keep SERIAL2_DELTA = 17!
When the physical locations of pin_TX2 and pin_RX2 are configurable for a specific
PIC, the device file will probably contain names like pin_TX2_RC2 and pin_RX2_RC1
and another pair with other pin suffixes.
Depending for which pair of pins the USART is configured aliases
without suffixes have to be specified, like:
alias pin_TX3 is pin_TX3_RC2
alias pin_RX3 is pin_RX3_RC1
alias pin_TX3_direction is pin_TX3_RC2_direction
alias pin_RX3_direction is pin_RX3_RC1_direction
2. Include this library.
and somewhere before actually using serial communications:
3. Prepare pins
pin_B4_direction = OUTPUT -- incoming data flow control

Notes

- pin_TX3 and pin_RX3 are selected automatically
- direction settings of these pins are taken care of by the library
.
4. Call serial_hw3_init() to initialize serial communications.
See serial_hw_int_cts library for background information.

Sources

Based on the serial_hw_int_cts2.jal library by Rob Hamerling.
----------------------------------------------------------------------
Setup defaults when no value is specified before:

Constants and Variables

serial3_overflow_discard - const bit = FALSE -- no transmit overflow
no transmit overflow

Routines

  • _serial3_receive_interrupt_handler - Procedure
  • _serial3_transmit_interrupt_handler - Procedure
  • serial3_send_byte - Function returns byte
  • serial_hw3_data'get - Function returns byte
  • serial_hw3_data'put - Procedure
  • serial_hw3_data_available - Function returns bit
  • serial_hw3_data_ready - Function returns bit
  • serial_hw3_init - Procedure
  • serial_hw3_read - Function returns bit
  • serial_hw3_tx_buffer_free - Function returns byte
  • serial_hw3_write - Procedure


serial_hw3_read - JALlib Procedures Help

serial_hw3_read JALLIB FUNCTION

Signature

function serial_hw3_read(byte out data) return bit is

Description

Title: Receive byte
Arguments: (none)
Returns: bit:
- TRUE data available
- FALSE no data available

Include

To use this procedure, include the library:

include serial_hardware3

Parameters

  • data - byte out

Return Value

bit - bit: TRUE data available FALSE no data available

Example

From sample file: 18f47q43_serial_hardware3.jal

-- -----------------------------------------------------------------------------
-- Title: Serial hardware test program for USART 3.
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: USART test program for the Microchip PIC18F47Q43. The program
--              will write a sequence of '.' to the serial port and will echo
--              any character that is received on the serial port.
--
-- Sources: Based on the serial hardware sample program by Joep Suijs.
--
-- Notes:
--
-- -----------------------------------------------------------------------------
--
include 18f47q43                -- target PICmicro
--
pragma target clock 20_000_000  -- oscillator frequency
--
pragma target OSC      HS       -- crystal or resonator
pragma target CLKOUTEN DISABLED -- no clock output
pragma target WDT      DISABLED -- watchdog
pragma target XINST    DISABLED -- do not use extended instructionset
pragma target BROWNOUT DISABLED -- no brownout reset
pragma target FCMEN    DISABLED -- no clock monitoring
pragma target CSWEN    ENABLED  -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED  -- low voltage programming
pragma target MCLR     EXTERNAL -- external reset
pragma target MVECEN   DISABLED -- Do no use multi vectored interrupts

enable_digital_io()             -- make all pins digital I/O

-- PPS is needed to set the USART pins correctly.
include pps
pps_control_lock(FALSE)
-- Change following lines to match your pcb layout.
RB0PPS  = PPS_TX3   -- TX3 assigned to B0
U3RXPPS = PPS_RB1   -- B1 assigned to RX3
pps_control_lock(TRUE)

const serial_hw3_baudrate = 115200
alias pin_tx3_direction	is pin_B0_direction
alias pin_rx3_direction	is pin_B1_direction
include serial_hardware3
serial_hw3_init()

include print
print_string(serial_hw3_data, "Hello serial hardware 3 world!")

-- let's build our loop
var byte char	-- will store received char
var word counter = 10

forever loop

   -- if there is a char, echo it back.
   if (serial_hw3_read(char)) then
      serial_hw3_write(char)  -- that's the echo...
   end if

   -- code block below prints a dot, every now and then, to signal
   -- the pic is alive
   counter = counter - 1     -- count down
   if (counter == 0) then    -- until zero
      counter = 50000        -- then start over counting from 50000
      serial_hw3_data = "."  -- and output a dot to the serial port
   end if

end loop

Generated by JALlib CHM Help System | Source: serial_hardware3.jal


serial_hw3_write - JALlib Procedures Help

serial_hw3_write JALLIB PROCEDURE

Signature

procedure serial_hw3_write(byte in data) is

Description

Title: Transmit character
Arguments: Data (byte) to transmit
Returns: (nothing)
Notes: Hardware transmit buffer must be empty, wait if necessary

Include

To use this procedure, include the library:

include serial_hardware3

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f47q43_serial_hardware3.jal

-- -----------------------------------------------------------------------------
-- Title: Serial hardware test program for USART 3.
-- Author: Rob Jansen, Copyright (c) 2021..2021 all rights reserved.
-- Adapted-by:
--
-- Compiler: 2.5r5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: USART test program for the Microchip PIC18F47Q43. The program
--              will write a sequence of '.' to the serial port and will echo
--              any character that is received on the serial port.
--
-- Sources: Based on the serial hardware sample program by Joep Suijs.
--
-- Notes:
--
-- -----------------------------------------------------------------------------
--
include 18f47q43                -- target PICmicro
--
pragma target clock 20_000_000  -- oscillator frequency
--
pragma target OSC      HS       -- crystal or resonator
pragma target CLKOUTEN DISABLED -- no clock output
pragma target WDT      DISABLED -- watchdog
pragma target XINST    DISABLED -- do not use extended instructionset
pragma target BROWNOUT DISABLED -- no brownout reset
pragma target FCMEN    DISABLED -- no clock monitoring
pragma target CSWEN    ENABLED  -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED  -- low voltage programming
pragma target MCLR     EXTERNAL -- external reset
pragma target MVECEN   DISABLED -- Do no use multi vectored interrupts

enable_digital_io()             -- make all pins digital I/O

-- PPS is needed to set the USART pins correctly.
include pps
pps_control_lock(FALSE)
-- Change following lines to match your pcb layout.
RB0PPS  = PPS_TX3   -- TX3 assigned to B0
U3RXPPS = PPS_RB1   -- B1 assigned to RX3
pps_control_lock(TRUE)

const serial_hw3_baudrate = 115200
alias pin_tx3_direction	is pin_B0_direction
alias pin_rx3_direction	is pin_B1_direction
include serial_hardware3
serial_hw3_init()

include print
print_string(serial_hw3_data, "Hello serial hardware 3 world!")

-- let's build our loop
var byte char	-- will store received char
var word counter = 10

forever loop

   -- if there is a char, echo it back.
   if (serial_hw3_read(char)) then
      serial_hw3_write(char)  -- that's the echo...
   end if

   -- code block below prints a dot, every now and then, to signal
   -- the pic is alive
   counter = counter - 1     -- count down
   if (counter == 0) then    -- until zero
      counter = 50000        -- then start over counting from 50000
      serial_hw3_data = "."  -- and output a dot to the serial port
   end if

end loop

Generated by JALlib CHM Help System | Source: serial_hardware3.jal


serial_hw_data_available - JALlib Procedures Help

serial_hw_data_available JALLIB FUNCTION

Signature

function serial_hw_data_available() return bit is

Description

generic (pic-independent) variable to check if a byte is received

Include

To use this procedure, include the library:

include serial_hardware

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: serial_hardware.jal


serial_hw_data'get - JALlib Procedures Help

serial_hw_data'get JALLIB PSEUDO VARIABLE

Signature

function serial_hw_data'get() return byte is

Description

Title: Receive byte
Arguments: (none)
Returns: Data (byte) received
Notes: This pseudo variable allows a language construct like
databyte = serial_hw_data
to receive a byte from the serial port into variable 'databyte'

Include

To use this procedure, include the library:

include serial_hardware

Parameters

None

Return Value

byte - Data (byte) received

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: serial_hardware.jal


serial_hw_data'put - JALlib Procedures Help

serial_hw_data'put JALLIB PSEUDO VARIABLE

Signature

procedure serial_hw_data'put(byte in data) is

Description

Title: Transmit byte
Arguments: Data (byte) to be transmitted
Returns: (nothing)
Notes: This pseudo variable allows a language construct like
serial_hw_data =
to transmit a byte to the seial port

Include

To use this procedure, include the library:

include serial_hardware

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: serial_hardware.jal


serial_hw_init - JALlib Procedures Help

serial_hw_init JALLIB PROCEDURE

Signature

procedure serial_hw_init() is

Description

Title: Initialize the (first or only) serial port
Arguments: (none)
Returns: (nothing)

Include

To use this procedure, include the library:

include serial_hardware

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: serial_hardware.jal


serial_hw_int_cts.jal - JALLIB Library Documentation

serial_hw_int_cts.jal JALLIB LIBRARY

Title

serial_hw_int_cts.jal. Interrupt driven buffered serial interface with flow control.

Author

Rob Hamerling, Copyright (c) 2008..2020, all rights reserved., Adapted-by: Joep Suijs, Rob Jansen

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Serial communications for first or only USART:
- receive and transmit data transfer is interrupt driven
- receive and transmit data transfer is buffered (circular buffers)
- provides automatic CTS flow control with spare free space for FiFo buffer
.
This library supports:
- Data format: 8 bits data, 1 start-bit, 1 stop bit
- Acceptable baud rate depends on the oscillator frequency
(see BAUD RATES tables in the datasheet).
- Interrupt bits used: TXIE, RCIE, PEIE and GIE.
.
Available procedures/functions for application programs:
.
- serial_hw_init() -- initialize communications
.
- serial_send_byte(byte out <byte>) -- send byte
-- returns the transmitted byte
- serial_hw_read(byte out <byte>) return bit -- receive byte
-- returns TRUE with data,
-- FALSE when no data available
- serial_hw_write(byte in <byte>) -- send byte (wait if queue full)
.
- serial_hw_data = <byte> -- send byte, wait if queue full
.
- serial_hw_tx_buffer_free() -- get free bytes in transmit buffer
-- returns number of free bytes
.
- <byte> = serial_hw_data -- receive byte, wait if queue empty
.
Directions for use of this library in application programs (in this sequence):
.
1. Declare the following constants:
.
const serial_hw_baudrate = 115200 -- line speed must be declared (no default)
.
const bit serial_overflow_discard = FALSE -- Transmit buffer overflow:
-- FALSE: wait for free space (blocking)
-- TRUE: discard data (non-blocking)
-- This flag may be dynamically changed
-- but must then be declared as 'var bit'
.
-- Receive buffer overflow data is
-- prevented by CTS flow control, provided
-- the sender has flow control enabled.
-- Otherwise data discarded without notification!
.
and an alias
.
alias serial_ctsinv is pin_B4 -- Incoming data flow control signal
-- Optional, if no CTS flow control needed
-- no dummy needs to be declared.
.
and optionally you could define one or more of the constants below.
You should do so if you want different values than shown (= default).
If not defined, the following values are used:
.
const SERIAL_XMTBUFSIZE = 32 -- size of transmit buffer
const SERIAL_RCVBUFSIZE = 64 -- size of receive buffer
const SERIAL_DELTA = 17 -- spare space receive buffer
-- if possible keep SERIAL_DELTA = 17!
.
When the physical locations of pin_TX and pin_RX are configurable for a specific
PIC, the device file will probably contain names like pin_TX_RB2 and pin_RX_RB1
and another pair with other pin suffixes.
Depending for which pair of pins the USART is configured aliases
without suffixes have to be specified, like:
alias pin_TX is pin_TX_RB2
alias pin_RX is pin_RX_RB1
alias pin_TX_direction is pin_TX_RB2_direction
alias pin_RX_direction is pin_RX_RB1_direction
.
2. Include this library.
.
and somewhere before actually using serial communications:
.
3. Prepare pins:
pin_B4_direction = OUTPUT -- incoming data flow control

Notes

- pin_TX and pin_RX are selected automatically
- direction settings of these pins are taken care of by the library
.
4. Call serial_hw_init() to initialize serial communications.
Background information:
.
The PIC ports use positive logic: '1' is positive voltage, '0' is ground.
.
In the RS232 standard:
- Negative voltage ('mark') means OFF for control signals, and
indicates 1 (one) for data signals (start-, data-, stop-bits).
- Positive voltage ('space') means ON for control signals and
0 (zero) for start-, data- and stop-bits.

Constants and Variables

serial_overflow_discard - const bit = FALSE -- no transmit overflow
no transmit overflow
BAUDCON_BRG16 - var bit = TRUE

Routines

  • _serial_receive_interrupt_handler - Procedure
  • _serial_transmit_interrupt_handler - Procedure
  • serial_hw_data'get - Function returns byte
  • serial_hw_data'put - Procedure
  • serial_hw_data_available - Function returns bit
  • serial_hw_data_ready - Function returns bit
  • serial_hw_init - Procedure
  • serial_hw_read - Function returns bit
  • serial_hw_tx_buffer_free - Function returns byte
  • serial_hw_write - Procedure
  • serial_init - Procedure
  • serial_receive_byte - Function returns bit
  • serial_send_byte - Function returns byte


serial_hw_read - JALlib Procedures Help

serial_hw_read JALLIB FUNCTION

Signature

function serial_hw_read(byte out data) return bit is

Description

Title: Receive byte
Arguments: (none)
Returns: bit:
- TRUE data available
- FALSE no data available

Include

To use this procedure, include the library:

include serial_hardware

Parameters

  • data - byte out

Return Value

bit - bit: TRUE data available FALSE no data available

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: serial_hardware.jal


serial_hw_write - JALlib Procedures Help

serial_hw_write JALLIB PROCEDURE

Signature

procedure serial_hw_write(byte in data) is

Description

Title: Transmit byte
Arguments: Data (byte) to transmit
Returns: (nothing)
Notes: Hardware transmit buffer must be empty, wait if not

Include

To use this procedure, include the library:

include serial_hardware

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: serial_hardware.jal


serial_newline - JALlib Procedures Help

serial_newline JALLIB PROCEDURE

Signature

procedure serial_newline() is

Description

No description available.

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


serial_print_spc - JALlib Procedures Help

serial_print_spc JALLIB PROCEDURE

Signature

procedure serial_print_spc() is

Description

No description available.

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


serial_send_byte - JALlib Procedures Help

serial_send_byte JALLIB FUNCTION

Signature

function serial_send_byte(byte in data) return byte is

Description

Title: Put a single byte in transmit buffer
Arguments: Data (byte) to transmit
Returns: transmitted byte (or 0x00 when data discarded)
Notes: - Activates transmit interrupt handler when data buffered
- When buffer full act as indicated in 'serial_overflow_discard'
* TRUE: discard data (and return 0x00 as data byte)
* FALSE: wait for free buffer space
(returns only after data has been stored in buffer)

Include

To use this procedure, include the library:

include serial_hw_int_cts

Parameters

  • data - byte in

Return Value

byte - transmitted byte (or 0x00 when data discarded)

Example

From sample file: 16f88_serial_hw_int_cts_echo.jal

-- =======================================================================
-- Title: Test program for serial_hw_int_cts library.
--
-- Author: Rob Hamerling, Copyright (c) 2008..2008, all rights reserved.
--
-- Adapted-by: Albert Faber
--
-- Compiler: =2.4l
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Program to test the serial_hw_int_cts library.
--                - Echo incoming byte multiple times to check
--                  transmit buffer overflow handling.
--                - The host program may use a hardware FiFo buffer
--                  (standard in most serial PC ports) to test
--                  CTS flow control and receive buffer overflow.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Dependencies:  serial_hw_int_cts.jal       (RS232 library)
--
-- Notes: - With a serial port monitor data loss and the working of
--          of data flow control can be checked.
--
-- -----------------------------------------------------------------------

include 16F88                                   -- target: PIC16F88

pragma target clock 16_000_000                  -- resonator frequency

pragma  bootloader long_start                   -- for TinyBootloader

pragma target OSC        hs
pragma target WDT        disabled
pragma target PWRTE      enabled
pragma target MCLR       external
pragma target BROWNOUT   enabled
pragma target LVP        enabled
pragma target CPD        disabled
pragma target WRT        disabled
pragma target DEBUG      disabled
pragma target CCP1MUX    pin_B0
pragma target CP         disabled
pragma target IESO       disabled
pragma target FCMEN      disabled

enable_digital_io()                           -- disable analog functions

-- ------- serial communications specifications --------------------------

const   SERIAL_XMTBUFSIZE  = 24             -- size of transmit buffer
const   SERIAL_RCVBUFSIZE  = 48             -- size of receive buffer
const   SERIAL_DELTA       = 17             -- spare rcv buffer space

const   SERIAL_HW_BAUDRATE = 57600          -- host communications

var  bit  serial_overflow_discard = FALSE   -- do not discard output!
alias serial_ctsinv is pin_B4               -- incomping data flow ctl
pin_B4_direction  = output

include serial_hw_int_cts                   -- RS232 library

serial_hw_init()

-- ------- ----------------------------------------------------------------

var   byte  x

forever loop

   if (serial_hw_read(x) == true) then      -- byte available
      for SERIAL_XMTBUFSIZE + 10 loop       -- more than fits in xmt buffer!
        x = serial_send_byte(x)             -- echo every char many times
      end loop
   end if

end loop

Generated by JALlib CHM Help System | Source: serial_hw_int_cts.jal


serial_software.jal - JALLIB Library Documentation

serial_software.jal JALLIB LIBRARY

Title

Software RS232 library

Author

Stef Mientki, Copyright (c) 2002..2020, all rights reserved., Adapted-by: Sebastien Lelong, Albert Faber, Joep Suijs (on behalf of Tijs van Roon),

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Software RS232 library
Library supports software RS232 send and receive procedure on any IO-pin.
Both the inverted and non-inverted routines are available,
so it should fit any hardware.
Baudrate can be set between 110 and 230_400 (for 20 Mhz Xtal),
for lower Xtal frequencies the maximum baudrate will be equally lower.
Baudrates are optimized, so even the high baudrates shouldn't be a problem
(my [Stef] standard = 115_200 Baud, which has never given me any problems).
Interrupts are disabled during transmissions.
Default parameters are 8 databits, 2 stopbits, no parity, no handshake.
.
To use this serial_software library in a user program:
.
1. The following aliases must be defined:
serial_sw_tx_pin is pin_xy (any output pin)
serial_sw_rx_pin is pin_xy (any input pin)
.
2. the following constants must be defined by the user program:
serial_sw_baudrate = 110 .. 240_000
.
3. The following constants may [optionally] be defined by the user program:
serial_sw_invert = FALSE | TRUE (default: TRUE)
serial_sw_databits = 5 .. 8 (default: 8)
serial_sw_stopbits = 1 | 2 (default: 2)
.
4. Include serial_software
.
5. Set the selected serial_sw_tx_pin for output and
set the serial_sw_rx_pin for input.
.
6. serial_sw_init()
----------------------------------------------------------------------------

Serial software aliases.

Constants and Variables

serial_sw_invert - const bit = true

Routines

  • serial_sw_data'get - Function returns byte
  • serial_sw_data'put - Procedure
  • serial_sw_init - Procedure
  • serial_sw_read - Function returns bit
  • serial_sw_read_wait - Procedure
  • serial_sw_write - Procedure


serial_sw_init - JALlib Procedures Help

serial_sw_init JALLIB PROCEDURE

Signature

procedure serial_sw_init() is

Description

Initialize the library
The only action needed is to set the transmit pin high or low,
(depending on serial_sw_invert definition).

Include

To use this procedure, include the library:

include serial_software

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_serial_sw_echo.jal

-- Title: Sample using software implemented USART.
-- Author: Sebastien Lelong, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to setup a simple software serial communication link.
-- It echoes every received char.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_serial_sw_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
-- setup speed. Standard values are: 57_600, 19_200, 9_600, 2_400, ...
-- Note: as it's a software implementation, not all baudrates can work with
-- our any clock. Higher speeds gives too much errors. We'll use a lower
-- baudrate here.
--
-- because it's a software implementation, we also need to define
-- tx and rx pins. How clever we are: we use the same pin as in hardware,
-- so it works out of the box with any board having an USART module...
--
-- finally, how levels are understood ? Inverted or not ?
-- Note in hardware serial, it's inverted. Since we're talking to a PC
-- we need to invert the signal
;@jallib section serial_software
alias serial_sw_tx_pin           is pin_C6
alias serial_sw_tx_pin_direction is pin_C6_direction
alias serial_sw_rx_pin           is pin_C7
const serial_sw_baudrate = 9600
const serial_sw_invert = true

serial_sw_tx_pin_direction = output

-- now we can use serial_software module
include serial_software
-- initialize the whole with our parameters
serial_sw_init()

-- inform user PIC is ready !
serial_sw_write("!")

-- let's build our loop
var byte char	-- will store received char
forever loop
    if serial_sw_read(char)
    then
        serial_sw_write(char)	-- that's the echo...
    end if
end loop

Generated by JALlib CHM Help System | Source: serial_software.jal


serial_sw_read - JALlib Procedures Help

serial_sw_read JALLIB FUNCTION

Signature

function serial_sw_read(byte out data) return bit is

Description

Wait until a character is received or time out is reached.
Interrupts will be disabled during this routine, but restored afterwards.
Also here the code is doubled (inverting and non-inverting)
and selection is done by a compiler-directive.

Include

To use this procedure, include the library:

include serial_software

Parameters

  • data - byte out

Return Value

bit - Function return value

Example

From sample file: 18f67j50_serial_sw_echo.jal

-- Title: Sample using software implemented USART.
-- Author: Sebastien Lelong, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to setup a simple software serial communication link.
-- It echoes every received char.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_serial_sw_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
-- setup speed. Standard values are: 57_600, 19_200, 9_600, 2_400, ...
-- Note: as it's a software implementation, not all baudrates can work with
-- our any clock. Higher speeds gives too much errors. We'll use a lower
-- baudrate here.
--
-- because it's a software implementation, we also need to define
-- tx and rx pins. How clever we are: we use the same pin as in hardware,
-- so it works out of the box with any board having an USART module...
--
-- finally, how levels are understood ? Inverted or not ?
-- Note in hardware serial, it's inverted. Since we're talking to a PC
-- we need to invert the signal
;@jallib section serial_software
alias serial_sw_tx_pin           is pin_C6
alias serial_sw_tx_pin_direction is pin_C6_direction
alias serial_sw_rx_pin           is pin_C7
const serial_sw_baudrate = 9600
const serial_sw_invert = true

serial_sw_tx_pin_direction = output

-- now we can use serial_software module
include serial_software
-- initialize the whole with our parameters
serial_sw_init()

-- inform user PIC is ready !
serial_sw_write("!")

-- let's build our loop
var byte char	-- will store received char
forever loop
    if serial_sw_read(char)
    then
        serial_sw_write(char)	-- that's the echo...
    end if
end loop

Generated by JALlib CHM Help System | Source: serial_software.jal


serial_sw_write - JALlib Procedures Help

serial_sw_write JALLIB PROCEDURE

Signature

procedure serial_sw_write(byte in data) is

Description

Transmit a character.
Interrupts will be disabled during this routine, but restored afterwards.
Also here the code is doubled (inverting and non-inverting)
and selection is done by a compiler-directive.

Include

To use this procedure, include the library:

include serial_software

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f67j50_serial_sw_echo.jal

-- Title: Sample using software implemented USART.
-- Author: Sebastien Lelong, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to setup a simple software serial communication link.
-- It echoes every received char.
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_serial_sw_echo.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

include delay

-- set all IO as digital
enable_digital_io()

-- ok, now setup serial
-- setup speed. Standard values are: 57_600, 19_200, 9_600, 2_400, ...
-- Note: as it's a software implementation, not all baudrates can work with
-- our any clock. Higher speeds gives too much errors. We'll use a lower
-- baudrate here.
--
-- because it's a software implementation, we also need to define
-- tx and rx pins. How clever we are: we use the same pin as in hardware,
-- so it works out of the box with any board having an USART module...
--
-- finally, how levels are understood ? Inverted or not ?
-- Note in hardware serial, it's inverted. Since we're talking to a PC
-- we need to invert the signal
;@jallib section serial_software
alias serial_sw_tx_pin           is pin_C6
alias serial_sw_tx_pin_direction is pin_C6_direction
alias serial_sw_rx_pin           is pin_C7
const serial_sw_baudrate = 9600
const serial_sw_invert = true

serial_sw_tx_pin_direction = output

-- now we can use serial_software module
include serial_software
-- initialize the whole with our parameters
serial_sw_init()

-- inform user PIC is ready !
serial_sw_write("!")

-- let's build our loop
var byte char	-- will store received char
forever loop
    if serial_sw_read(char)
    then
        serial_sw_write(char)	-- that's the echo...
    end if
end loop

Generated by JALlib CHM Help System | Source: serial_software.jal


servo_init - JALlib Procedures Help

servo_init JALLIB PROCEDURE

Signature

procedure servo_init() is

Description

Initialize the servo

Include

To use this procedure, include the library:

include servo_rc_master

Parameters

None

Return Value

None

Example

From sample file: 18f4620_servo_rc_master.jal

-- Title: servo control sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample controls up to 24 servos that are the type used in radio
--              control (RC) and also turns a led on and off after each movement.
--
-- Sources:
-- http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html
--
-- notes:
-- See usage notes in library file servo_rc_master.jal, very important!
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup servo pins
alias servo_1             is pin_a0
alias servo_1_direction   is pin_a0_direction
servo_1_direction = output
--
alias servo_2             is pin_a1
alias servo_2_direction   is pin_a1_direction
servo_2_direction = output
--
;alias servo_3             is pin_b2
;alias servo_3_direction   is pin_b2_direction
;servo_3_direction = output
--
;alias servo_4             is pin_b3
;alias servo_4_direction   is pin_b3_direction
;servo_4_direction = output
--
;alias servo_5             is pin_b4
;alias servo_5_direction   is pin_b4_direction
;servo_5_direction = output
--
;alias servo_6             is pin_b5
;alias servo_6_direction   is pin_b5_direction
;servo_6_direction = output
--
;alias servo_7             is pin_b6
;alias servo_7_direction   is pin_b6_direction
;servo_7_direction = output
--
;alias servo_8             is pin_b7
;alias servo_8_direction   is pin_b7_direction
;servo_8_direction = output
--
;alias servo_9             is pin_a0
;alias servo_9_direction   is pin_a0_direction
;servo_9_direction = output
--
-- choose min & max servo movment / pulse size
const byte SERVO_MIN   = 50  -- default is 50  (0.5ms min pulse)
const byte SERVO_MAX   = 255 -- default is 255 (2.5ms max pulse)
--
-- choose pic internal timers
const byte SERVO_USE_TIMER = 0            -- timer for servo's 1 to 8
;const byte SERVO_9_TO_16_USE_TIMER = 1    -- timer for servo's 9 to 16
;const byte SERVO_17_TO_24_USE_TIMER = 3   -- timer for servo's 17 to 24
include servo_rc_master -- include the servo library
servo_init()

-- use this to turn off a servo
;servo_1_on = FALSE

-- use this to reverse a servo
;servo_1_reverse = TRUE

-- example center all servo's
servo_move(127,1)
servo_move(127,2)
servo_move(127,3)
servo_move(127,4)
servo_move(127,5)
servo_move(127,6)
servo_move(127,7)
servo_move(127,8)
;servo_move(127,9)

_usec_delay (1_000_000)

-- example moving servos one and two and blink led
forever loop
   servo_move(255,1)
   servo_move(0,2)
   _usec_delay (1_000_000)

   servo_move(127,1) ;servo 1 centered
   servo_move(127,2) ;servo 2 centered
   _usec_delay (1_000_000)

   servo_move(0,1)
   servo_move(255,2)
   _usec_delay (1_000_000)

   servo_move(127,1) ;servo 1 centered
   servo_move(127,2) ;servo 2 centered
   _usec_delay (1_000_000)
end loop

Generated by JALlib CHM Help System | Source: servo_rc_master.jal


servo_move - JALlib Procedures Help

servo_move JALLIB PROCEDURE

Signature

procedure servo_move(byte in location, byte in servo_number) is

Description

Move a servo to any location from 0 to 255

Include

To use this procedure, include the library:

include servo_rc_master

Parameters

  • location - byte in
  • servo_number - byte in

Return Value

None

Example

From sample file: 18f4620_servo_rc_master.jal

-- Title: servo control sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample controls up to 24 servos that are the type used in radio
--              control (RC) and also turns a led on and off after each movement.
--
-- Sources:
-- http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html
--
-- notes:
-- See usage notes in library file servo_rc_master.jal, very important!
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup servo pins
alias servo_1             is pin_a0
alias servo_1_direction   is pin_a0_direction
servo_1_direction = output
--
alias servo_2             is pin_a1
alias servo_2_direction   is pin_a1_direction
servo_2_direction = output
--
;alias servo_3             is pin_b2
;alias servo_3_direction   is pin_b2_direction
;servo_3_direction = output
--
;alias servo_4             is pin_b3
;alias servo_4_direction   is pin_b3_direction
;servo_4_direction = output
--
;alias servo_5             is pin_b4
;alias servo_5_direction   is pin_b4_direction
;servo_5_direction = output
--
;alias servo_6             is pin_b5
;alias servo_6_direction   is pin_b5_direction
;servo_6_direction = output
--
;alias servo_7             is pin_b6
;alias servo_7_direction   is pin_b6_direction
;servo_7_direction = output
--
;alias servo_8             is pin_b7
;alias servo_8_direction   is pin_b7_direction
;servo_8_direction = output
--
;alias servo_9             is pin_a0
;alias servo_9_direction   is pin_a0_direction
;servo_9_direction = output
--
-- choose min & max servo movment / pulse size
const byte SERVO_MIN   = 50  -- default is 50  (0.5ms min pulse)
const byte SERVO_MAX   = 255 -- default is 255 (2.5ms max pulse)
--
-- choose pic internal timers
const byte SERVO_USE_TIMER = 0            -- timer for servo's 1 to 8
;const byte SERVO_9_TO_16_USE_TIMER = 1    -- timer for servo's 9 to 16
;const byte SERVO_17_TO_24_USE_TIMER = 3   -- timer for servo's 17 to 24
include servo_rc_master -- include the servo library
servo_init()

-- use this to turn off a servo
;servo_1_on = FALSE

-- use this to reverse a servo
;servo_1_reverse = TRUE

-- example center all servo's
servo_move(127,1)
servo_move(127,2)
servo_move(127,3)
servo_move(127,4)
servo_move(127,5)
servo_move(127,6)
servo_move(127,7)
servo_move(127,8)
;servo_move(127,9)

_usec_delay (1_000_000)

-- example moving servos one and two and blink led
forever loop
   servo_move(255,1)
   servo_move(0,2)
   _usec_delay (1_000_000)

   servo_move(127,1) ;servo 1 centered
   servo_move(127,2) ;servo 2 centered
   _usec_delay (1_000_000)

   servo_move(0,1)
   servo_move(255,2)
   _usec_delay (1_000_000)

   servo_move(127,1) ;servo 1 centered
   servo_move(127,2) ;servo 2 centered
   _usec_delay (1_000_000)
end loop

Generated by JALlib CHM Help System | Source: servo_rc_master.jal


servo_rc_master.jal - JALLIB Library Documentation

servo_rc_master.jal JALLIB LIBRARY

Title

servo control library

Author

Matthew Schinkel, copyright (c) 2009..2019, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library controls up to 24 servos that are the type used in
radio control (RC). This is the main servo library.

Sources

http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html
usage notes:
1. Set your servo_min values to restrict movement.
This step should be completed. First use code as follows
directly after you call servo_init()
servo_move(0,1)
forever loop
end loop
Now run your circuit and gradually increase servo_min value so the servo
is at the correct location on one side. Try to get the servo to be
1mm from it's min location.
2. Repeat step 1 by decreasing servo_max but use this:
servo_move(255,1)
forever loop
end loop
other notes:
This lib uses timer0, timer1 or timer3
Up to 24 servos are supported
Newer PICs with different timer registers is supported by looking at the
existence of PIE4_TMR1IE like for the PIC16F15325. There is no timer3 for
this PIC.

check if current pic has selected timers

use these bit variables to reverse servo direction

Constants and Variables

servo_reverse - var byte = 0x00 -- All servo's on by default
All servo's on by default
servo_1_to_8_on - var byte = 0xFF -- All servo's on by default
All servo's on by default
servo_9_to_16_reverse - var byte = 0x00
servo_9_to_16_on - var byte = 0xFF -- All servo's on by default
All servo's on by default
servo_17_to_24_reverse - var byte = 0x00
servo_17_to_24_on - var byte = 0xFF -- All servo's on by default
All servo's on by default

Routines

  • _servo_17_to_24_set_level - Procedure
  • _servo_1_to_8_set_level - Procedure
  • _servo_9_to_16_set_level - Procedure
  • _servo_isr - Procedure
  • servo_init - Procedure
  • servo_move - Procedure
  • servo_move_percent - Procedure


servo_rc_master_dedicated.jal - JALLIB Library Documentation

servo_rc_master_dedicated.jal JALLIB LIBRARY

Title

Library for use with a dedicated RC servo PIC

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library controls an external PIC that works as a slave device
and is a dedicated PIC to servo movements.

Notes

Also see servo_rc_master library, this is not the main servo library.
Master clock/oscillator should be equal or less then slave clock/osc
otherwise you may need to run a slower I2C bus.
if you set servo_rc_master_dedicated_wait to false, you will need to check
if the slave is ready by using the servo_rc_is_ready_i2c() function before
sending another command. device must be setting this as false will allow your
main program to continue while slave is still busy. Slave will stay busy for
about 1ms

Sources

http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html

servo commands that you may pass to the send_command procedure

Constants and Variables

SERVO_RC_COMMAND_MOVE - const byte = 0 -- move command
move command
SERVO_RC_COMMAND_REVERSE - const byte = 32 -- reverse servo command
reverse servo command
SERVO_RC_COMMAND_ON_OFF - const byte = 64 -- turn servo on/off
turn servo on/off
SERVO_RC_COMMAND_MIN - const byte = 96 -- set servo min movement
set servo min movement
SERVO_RC_COMMAND_MAX - const byte = 128 -- set servo max movement
set servo max movement

Routines

  • servo_rc_error_i2c - Function returns bit
  • servo_rc_is_ready_i2c - Function returns bit
  • servo_rc_send_command_i2c - Procedure


servo_rc_send_command_i2c - JALlib Procedures Help

servo_rc_send_command_i2c JALLIB PROCEDURE

Signature

procedure servo_rc_send_command_i2c(byte in servo_ic_address, byte in command, byte in command_data, byte in servo_num) is

Description

send a command to the dedicated servo pic such as move, reverse, on/off
via I2C

Include

To use this procedure, include the library:

include servo_rc_master_dedicated

Parameters

  • servo_ic_address - byte in
  • command - byte in
  • command_data - byte in
  • servo_num - byte in

Return Value

None

Example

From sample file: 18f452_servo_rc_master_dedicated_master_i2c.jal

-- Title: Sample master to control a dedicated RC servo controller PIC
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4m
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample controls an external PIC that acts as a slave device
--              and is a dedicated PIC for servo movements. Slave PIC can support
--              24 servos that are the type used in radio control (RC)
--
-- This file has been generated by hand (manually maintained)
--
-- Notes:
-- See other servo samples before using this one
--
-- Master clock/oscillator should be equal or less then slave clock/osc
-- otherwise you may need to limit I2C bus speed.
--
-- The external pic should be written with a sample such as
-- 18fxxx_servo_rc_master_dedicated_slave_i2c.jal
--
-- Sources:
-- http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html
--

-- include chip
include 18f452                     -- target picmicro
pragma target clock 20_000_000     -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS              -- HS crystal or resonator
pragma target WDT  CONTROL        -- no watchdog
pragma target LVP  enabled         -- allow Low Voltage Programming

enable_digital_io()                -- make all pins digital I/O
-- Setup I2C
--
-- I2C pin definition
alias i2c_scl            is pin_c3
alias i2c_scl_direction  is pin_c3_direction
alias i2c_sda            is pin_c4
alias i2c_sda_direction  is pin_c4_direction
--
const word _i2c_bus_speed = 4 -- 400kHz
const bit _i2c_level = true   -- i2c levels (not SMB)
include i2c_software          -- include i2c software lib
i2c_initialize()              -- initialize i2c lib

-- Setup the dedicated pic servo library, to control an external servo pic.
--
-- specify weather to wait for slave device to be ready before continuing
-- main program. If set to false you must check the ready bit via ready function,
-- or delay 1ms between commands.
const byte SERVO_RC_MASTER_DEDICATED_WAIT = TRUE
--
-- include the dedicated servo library.
-- slave/dedicated pic runs servo_rc_master library.
include servo_rc_master_dedicated

-- main program here
var byte servo_ic_address = 0x6E -- the dedicate/external servo pic i2c address

-- set min/max movement. servo number cannot be selected, changing min/max
-- movement affects all servo's. if you do not sendA these 2 commands,
-- the default is min 50, max 250 (500us to 2.50ms pulses)
servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MIN, 50, 0)
servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MAX, 250, 0)

forever loop
   -- move pic 1 & 17 to center position
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 17)
   _usec_delay(1_000_000)

   -- move pic 1 & 17 to one side
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 255, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 255, 17)
   _usec_delay(1_000_000)

   -- move pic 1 & 17 to center position
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 127, 17)
   _usec_delay(1_000_000)

   -- move pic 1 & 17 to other side
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 0, 1)
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_MOVE, 0, 17)
   _usec_delay(1_000_000)

   -- reverse direction of servo 1
   servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_REVERSE, TRUE, 1)

   -- turn off servo 17
   ;servo_rc_send_command_i2c(servo_ic_address, SERVO_RC_COMMAND_ON_OFF, OFF, 17)
end loop

Generated by JALlib CHM Help System | Source: servo_rc_master_dedicated.jal


servo_rc_slave.jal - JALLIB Library Documentation

servo_rc_slave.jal JALLIB LIBRARY

Title

RC Servo Slave

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library allows your PIC to read pulses given by a RC
receiver. Connect your PIC to a rc receiver the same way you
would connect a RC servo. This library will output a value
dependant on where your fingers are moving the controls
on your remote transmitter. PIC will read the pulse width
at the receiver.

Sources

http://www.horrorseek.com/home/halloween/wolfstone/Motors/svoint_RCServos.html
notes:
TIMER0 only works as a 8 bit timer.

Constants and Variables

servo_high_value - var byte
servo_low_value - var byte
servo_slave_multiple - var word
servo_high_value - var word
servo_low_value - var word
servo_slave_multiple - var dword

Routines

  • int_on_change_callback_0 - Procedure
  • int_on_change_callback_0 - Procedure
  • int_on_change_callback_1 - Procedure
  • int_on_change_callback_1 - Procedure
  • int_on_change_callback_2 - Procedure
  • int_on_change_callback_2 - Procedure
  • int_on_change_callback_3 - Procedure
  • int_on_change_callback_3 - Procedure
  • servo_slave'get - Function returns byte
  • servo_slave_init - Procedure
  • servo_slave_timer_isr - Procedure


servo_slave_init - JALlib Procedures Help

servo_slave_init JALLIB PROCEDURE

Signature

procedure servo_slave_init() is

Description

Initialize the servo

Include

To use this procedure, include the library:

include servo_rc_slave

Parameters

None

Return Value

None

Example

From sample file: 18f4525_servo_rc_slave.jal

-- Title: RC Servo Slave sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample allows your PIC to read pulses given by a RC
--              receiver. Connect your PIC to a rc receiver the same way you
--              would connect a RC servo. This will use the rc_servo_slave
--              library to output a value to the serial port dependant on
--              where your fingers are moving the controls on your remote
--              transmitter. PIC will read the pulse width at the receiver.
--
-- Sources:
--
-- notes:
-- PIC must have interrupt on change pins on port B. If you are using another
-- port, INTCON_RBIE & INTCON_RBIF may be named differently.
-- Check your datasheet for a interrupt-on-change pin.
--
-- Connect clock_out pin directly to int_on_change pin for an example without
-- an actual RC receiver.
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- choose pins to use for interrupt on change
const byte int_on_change_pins[] = {"B",4,"B",5} -- interrupt on change pin 0 and 1,  B4 and B5
include interrupt_on_change
int_on_change_init()

-- setup servo slave lib
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_0 = TRUE -- use interrupt on change pin 0
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_1 = TRUE -- use interrupt on change pin 1
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_2 = 0 -- use interrupt on change pin 2
const byte SERVO_SLAVE_USE_INT_ON_CHANGE_PIN_3 = 0 -- use interrupt on change pin 3
--
const SERVO_SLAVE_USE_TIMER = 1     -- choose a timer
--
-- set your min/max values (0 to 100)
-- adjust SERVO_SLAVE_MIN first, then adjust SERVO_SLAVE_MAX
-- so output values will range from 0 to 255.
const SERVO_SLAVE_MIN = 0 -- default is 0
const SERVO_SLAVE_MAX = 0 -- default is 0
--
include servo_rc_slave
servo_slave_init()

-- Configure PWM
pin_ccp1_direction = output
include pwm_hardware
pwm_max_resolution(1)
pwm1_on() -- turn on PWM1
pwm2_on() -- turn on PWM1

-- define clock out pin
alias clock_out           is pin_a1
alias clock_out_direction is pin_a1_direction
clock_out_direction = output

-- main loop
forever loop
   -- create a pulse to measure
   -- if your receiver is not connected, you may use this signal.
   clock_out = high
   _usec_delay(1500) -- 500 to 2_500 (0.5ms to 2.5ms)
   clock_out = low
   _usec_delay(20_000)

   -- SIGNAL 1
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[0] == TRUE then
      -- set the led brightness
      pwm1_set_dutycycle_ratio( servo_slave[0] << 2)
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[0])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm1_set_dutycycle_ratio(0) -- turn led off
   end if

   serial_data = " "
   serial_data = "-"
   serial_data = " "

   -- SIGNAL 2
   -- test if there is a signal. If no signal, the transmitter
   -- may be out of range, off or low on batteries.
   if servo_slave_is_valid[1] == TRUE then
      -- set the led brightness
      pwm2_set_dutycycle_ratio( servo_slave[1] << 2 )
      -- send the value to the serial port
      print_dword_dec(serial_data, servo_slave[1])
   else
      -- there must be no pulse, send a message
      const byte str1[] = "No Signal!"
      print_string(serial_data, str1)
      pwm2_set_dutycycle_ratio(1) -- turn led off
   end if

   -- send crlf to serial port
   print_crlf(serial_data)
end loop

Generated by JALlib CHM Help System | Source: servo_rc_slave.jal


set_delay - JALlib Procedures Help

set_delay JALLIB PROCEDURE

Signature

procedure set_delay(byte in slot, word in ticks) is

Description

No description available.

Include

To use this procedure, include the library:

include timer0_isr_interval

Parameters

  • slot - byte in
  • ticks - word in

Return Value

None

Example

From sample file: 18f14k50_timer0_interval.jal

-- ----------------------------------------------------------------------------
-- Title: test timer0 interval
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: test the library timero_isr_interval
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_timer0_interval.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

led_direction = output

if (defined(led2)) then -- compile only when led2 is defined.
   led2_direction = output
end if

-- set all IO as digital
enable_digital_io()

-- setup the timer0_isr_interval library
const word timer0_isr_rate = 1000  -- 1 kHz isr rate
const DELAY_SLOTS = 2         -- support 2 delays at the same time
include timer0_isr_interval
timer0_isr_init()             -- init timer0 isr

var word prev_interval_counter

   forever loop

      if (isr_counter != prev_interval_counter) then
         prev_interval_counter = isr_counter
         -- put here code that you want
         -- to execute each tick.
      end if ; 1 kHz loop

      if (check_delay(0)) then
         set_delay(0, 409) -- 409 ticks on delay-slot 0
         led = !led
      end if
      if (defined(led2)) then -- compile only when led2 is defined.
         if (check_delay(1)) then
            set_delay(1, 619) -- 619 ticks on delay-slot 1
            led2 = !led2
         end if
      end if
   end loop

; end of main

Generated by JALlib CHM Help System | Source: timer0_isr_interval.jal


seven_from_digit - JALlib Procedures Help

seven_from_digit JALLIB FUNCTION

Signature

function seven_from_digit( byte in x ) return byte is

Description

return seven segment value corresponding to lower nibble of x

Include

To use this procedure, include the library:

include seven_segment

Parameters

  • x - byte in

Return Value

byte - Function return value

Example

From sample file: 18f67j50_sr_74595.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for 74595 shift register
--
-- Author: Joep Suijs, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    test setup: 3 x 74595 cascaded
--    sr_sda connects to SER_IN / DS pin of 74595 #1
--    SER_OUT / Q7S of 74595 #1 connects to SER_IN / DS pin of 74595 #2
--    SER_OUT / Q7S of 74595 #2 connects to SER_IN / DS pin of 74595 #3
--    sr_scl is connected the SRCK / SHCP pin of all three 74595 chips
--    sr_rck is connected the RCK / STCP pin of all three 74595 chips
--    sr_g is connected the G / OE pin of all three 74595 chips
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_sr_74595.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

enable_digital_io() -- disable analog I/O (if any)

include delay
include seven_segment

-- define IO pin's
alias sr_rck   is pin_a0   ; RCK (parallel clock / load, rising edge)
alias sr_sda   is pin_a1   ; SER_IN   / DS
alias sr_scl   is pin_a2   ; SRCK  (serial clock, rising egde)
alias sr_g     is pin_a3   ; G (output enable, low = enable)

-- set IO pins to output
pin_a0_direction = output
pin_a1_direction = output
pin_a2_direction = output
pin_a3_direction = output

-- include library & turn outputs on
include shift_register_74595
sr_output_enable(1)  ; activate shift register outputs

forever loop

   -- set one output of each shift register
   sr_write(1)   ; data for 74595 #3 (end of chain)
   sr_write(2)   ; data for 74595 #2 (middle one)
   sr_write(4)   ; data for 74595 #1 (directly connected to PIC)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- show numbers on seven segment display, connected to shift register
   sr_write(seven_from_digit(1))
   sr_write(seven_from_digit(2))
   sr_write(seven_from_digit(3))
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- clear outputs of all 3 shift registers
   sr_write(0)
   sr_write(0)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- set all outputs of shift register #1
   sr_write(255)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #2 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #3 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs are low now)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

end loop

Generated by JALlib CHM Help System | Source: seven_segment.jal


seven_segment.jal - JALLIB Library Documentation

seven_segment.jal JALLIB LIBRARY

Title

seven_segment.jal - translation routine for 7 segment display

Author

Wouter van Ooijen (c) 1998..2009, all rights reserved., Adapted-by: Joep Suijs, Vasile Surducan

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Translation routine for 7 segment display.
--
The seven segment display needs to be connected to a single port.
AAAAAA
F B
F B
F B
GGGGGG
E C
E C
E C
DDDDDD DP
If the pins on the port are not in sequence A..G, DP,
then, before including seven_segment.jal, define
the pin layout of the seven segment display like:
--
-- constant for the segments gfe dcba
const byte seven_segment_a = 0b_0000_0001
const byte seven_segment_b = 0b_0000_0010
const byte seven_segment_c = 0b_0000_0100
const byte seven_segment_d = 0b_0000_1000
const byte seven_segment_e = 0b_0001_0000
const byte seven_segment_f = 0b_0010_0000
const byte seven_segment_g = 0b_0100_0000
const byte seven_segment_dp = 0b_1000_0000
--
value 0 is character "0"
value 1 is character "1"
value 2 is character "2"
value 3 is character "3"
value 4 is character "4"
value 5 is character "5"
value 6 is character "6"
value 7 is character "7"
value 8 is character "8"
value 9 is character "9"
value 10 is character "A"
value 11 is character "b"
value 12 is character "C"
value 13 is character "d"
value 14 is character "E"
value 15 is character "F"
value 16 is character "S"
value 17 is character "c"
value 18 is character "r"
value 19 is character "H"
value 20 is character "i"
value 21 is character "L"
value 22 is character "o"
value 23 is character "P"
value 24 is character "U"
value 25 is character "G"
value 26 is character "u"
value 27 is character "space"
value 28 is character "J"
value 29 is character "n"
value 30 is character "h"
value 31 is character "celsius degree"
value 32 is character "_"
value 33 is character "="
value 34 is character "-"
value 35 is character "segment dp" (DOT)
value 36 is character "N"
--
Use:
--
const bit seven_segment_common_anode = true ; omit this line if you use a common cathode display.
--
portd_direction = all_output
portd = seven_from_digit(1) -- display '1'
--

Notes

Constants and Variables

seven_segment_common_anode - const bit = false -- default is common_cathode
default is common_cathode
seven_segment_a - const byte = 0b_0000_0001
seven_segment_b - const byte = 0b_0000_0010
seven_segment_c - const byte = 0b_0000_0100
seven_segment_d - const byte = 0b_0000_1000
seven_segment_e - const byte = 0b_0001_0000
seven_segment_f - const byte = 0b_0010_0000
seven_segment_g - const byte = 0b_0100_0000
seven_segment_dp - const byte = 0b_1000_0000

Routines

  • seven_from_digit - Function returns byte


seven_segment_multiplexer.jal - JALLIB Library Documentation

seven_segment_multiplexer.jal JALLIB LIBRARY

Title

Seven Segment Multiplexer

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Allows use of more than one 7 segement display by
switching (multiplexing) accross them via a timer.

Notes

Currently supports up to six 7 segement displays, but the library
can easily be changed to add more.

set common anode if user set the constant.

Constants and Variables

seven_segment_multiplexer_timer_interval - var word
TIMER0_PS_RATIO - const byte = 1 -- set prescaller ratio
set prescaller ratio
TIMER0_BITS - const byte = 16 -- Use 8 or 16 bits
Use 8 or 16 bits
TIMER0_ENABLE_INTERRUPT - const byte = TRUE -- Interrupts off/on
Interrupts off/on
TIMER1_PS_RATIO - const byte = 1 -- set prescaller ratio
set prescaller ratio
TIMER1_BITS - const byte = 16 -- Use 8 or 16 bits
Use 8 or 16 bits
TIMER1_ENABLE_INTERRUPT - const byte = TRUE -- Interrupts off/on
Interrupts off/on
TIMER3_PS_RATIO - const byte = 1 -- set prescaller ratio
set prescaller ratio
TIMER3_BITS - const byte = 16 -- Use 8 or 16 bits
Use 8 or 16 bits
TIMER3_ENABLE_INTERRUPT - const byte = TRUE -- Interrupts off/on
Interrupts off/on

Routines

  • seven_segment_multiplexer'put - Procedure
  • seven_segment_multiplexer_init - Procedure
  • seven_segment_multiplexer_isr - Procedure


seven_segment_multiplexer_init - JALlib Procedures Help

seven_segment_multiplexer_init JALLIB PROCEDURE

Signature

procedure seven_segment_multiplexer_init(word in freq) is

Description

Init procedure

Include

To use this procedure, include the library:

include seven_segment_multiplexer

Parameters

  • freq - word in

Return Value

None

Example

From sample file: 18f4620_seven_segment_multiplexer.jal

-- Title: Seven Segment Display Multiplexer
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample generates a count & displays it accross 3 seven
--              segment displays.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize
--
include delay                       -- library with delay procedures

-- setup seven segment multiplexer library.
alias seven_segment_multiplexer_segment0           is pin_a0
alias seven_segment_multiplexer_segment0_direction is pin_a0_direction
alias seven_segment_multiplexer_segment1           is pin_a1
alias seven_segment_multiplexer_segment1_direction is pin_a1_direction
alias seven_segment_multiplexer_segment2           is pin_a2
alias seven_segment_multiplexer_segment2_direction is pin_a2_direction
alias seven_segment_multiplexer_port               is portd
alias seven_segment_multiplexer_port_direction     is portd_direction
--
const SEVEN_SEGMENT_MULTIPLEXER_SEGMENTS  = 3 -- 3 digits
const SEVEN_SEGMENT_MULTIPLEXER_USE_TIMER = 0 -- use timer 0
const SEVEN_SEGMENT_MULTIPLEXER_COMMON_ANODE = TRUE
include seven_segment_multiplexer
seven_segment_multiplexer_init(100) -- 100hz multiplexing.

-- main program
var word step = 0
forever loop
   seven_segment_multiplexer = step -- Put the value of step onto the displays.

   delay_1ms(25)    -- a delay
   step = step + 1  -- increment step
end loop

Generated by JALlib CHM Help System | Source: seven_segment_multiplexer.jal


si5351a.jal - JALLIB Library Documentation

si5351a.jal JALLIB LIBRARY

Title

Library for the Si5351a programmable any frequence clock generator.

Author

Rob Jansen, Copyright (c) 2020..2020, all rights reserved., Adapted-by:

Compiler

2.5r4

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Libray for use of the Si5351a clock generator.

Notes

The following IIC pins must be defined by the main program before
including this library:
-) alias si5351a_scl -- To SCL of SI5351
-) alias si5351a_scl_direction
-) alias si5351a_sda -- To SDA of SI5351
-) alias si5351a_sda_direction
The default is hardware IIC control but this can be overruled using
software IIC control by defining the following constant:
-) const SI5351A_SOFTWARE_IIC = TRUE
The IIC slave address can be set by defining the following constant:
-) const byte SI5351A_IIC_ADDRESS = <IIC address>
This library uses by default the IIC address of the device with A0
being 0: 0b0110_0000.
The default crystal frequency is 25 MHz, this can be changed to
27 MHz by defining that frequency in Hz:
-) dword SI5351A_CRYSTAL_FREQUENCY = 27_000_000
Important: Although the library is designed to support the Si5351a
with 7 outputs, it has only been tested for the smaller
(10-MSOP) version with 3 outputs.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

IIC address, depends on what is used for A0. We assume here A0 = 0.

Sources

Inspired by the following sources:
-) https://github.com/etherkit/Si5351Arduino
-) https://radiotransmitter.wordpress.com/2017/02/23/a-simple-software-to-control-the-si5351a-generator-chip/
-) https://www.rfzero.net/tutorials/si5351a/
Application note AN619 from Silicon Labs.

Constants and Variables

SI5351A_IIC_ADDRESS - const byte = 0b0110_0000
SI5351A_CRYSTAL_FREQUENCY - const dword = 25_000_000
SI5351A_MIN_CLOCK - const byte = 1
SI5351A_MAX_CLOCK - const byte = 8
SI5351A_CLOCK_0 - const byte = 0
SI5351A_CLOCK_1 - const byte = 1
SI5351A_CLOCK_2 - const byte = 2
SI5351A_CLOCK_3 - const byte = 3
SI5351A_CLOCK_4 - const byte = 4
SI5351A_CLOCK_5 - const byte = 5
SI5351A_CLOCK_6 - const byte = 6
SI5351A_CLOCK_7 - const byte = 7
SI5351A_CLOCK_SOURCE_XTAL - const byte = 0b0000_0000
SI5351A_CLOCK_SOURCE_MULTISYNTH_0_4 - const byte = 0b0000_1000
SI5351A_CLOCK_SOURCE_MULTISYNTH_X - const byte = 0b0000_1100 -- X = 0..7.
X = 0..7.
SI5351A_CLOCK_DRIVE_2_MA - const byte = 0x00
SI5351A_CLOCK_DRIVE_4_MA - const byte = 0x01
SI5351A_CLOCK_DRIVE_6_MA - const byte = 0x02
SI5351A_CLOCK_DRIVE_8_MA - const byte = 0x03
SI5351A_CLOCK_DISABLE_STATE_LOW - const byte = 0x00
SI5351A_CLOCK_DISABLE_STATE_HIGH - const byte = 0x01
SI5351A_CLOCK_DISABLE_STATE_FLOAT - const byte = 0x02 -- High impedance state.
High impedance state.
SI5351A_CLOCK_DISABLE_STATE_NEVER - const byte = 0x03
SI5351A_CRYSTAL_LOAD_6_PF - const byte = 0b0101_0010
SI5351A_CRYSTAL_LOAD_8_PF - const byte = 0b1001_0010
SI5351A_CRYSTAL_LOAD_10_PF - const byte = 0b1101_0010
SI5351A_MIN_OUT_FREQUENCY - const dword = 2_500
SI5351A_MAX_OUT_FREQUENCY - const dword = 225_000_000
SI5351A_MIN_PLL_FREQUENCY - const dword = 600_000_000
SI5351A_MAX_PLL_FREQUENCY - const dword = 900_000_000
SI5351A_PLL_A - const byte = 0
SI5351A_PLL_B - const byte = 1
current_frequency - var dword
current_pll - var byte
all_ok - var bit
pll_frequency - var dword
all_ok - var bit
all_ok - var bit

Routines

  • _si5351a_calculate_output_setting - Function returns bit
  • _si5351a_calculate_pll_setting - Procedure
  • _si5351a_determine_maximum_pll_frequency - Function returns dword
  • _si5351a_pll_on_clock - Function returns byte
  • _si5351a_read_register - Function returns byte
  • _si5351a_recalculate_outputs - Function returns bit
  • _si5351a_update_all_clocks - Procedure
  • _si5351a_write_register - Procedure
  • _store_multisynth_data - Procedure
  • si5351a_crystal_signal_is_valid - Function returns bit
  • si5351a_disable_clock_output - Procedure
  • si5351a_disable_multisynth_fanout - Procedure
  • si5351a_disable_xo_fanout - Procedure
  • si5351a_enable_clock_output - Procedure
  • si5351a_enable_multisynth_fanout - Procedure
  • si5351a_enable_xo_fanout - Procedure
  • si5351a_get_revision_id - Function returns byte
  • si5351a_init - Procedure
  • si5351a_pll_a_is_locked - Function returns bit
  • si5351a_pll_b_is_locked - Function returns bit
  • si5351a_power_down_clock_output - Procedure
  • si5351a_power_up_clock_output - Procedure
  • si5351a_reset_pll_a - Procedure
  • si5351a_reset_pll_b - Procedure
  • si5351a_set_clock_disable_state - Procedure
  • si5351a_set_clock_drive_strength - Procedure
  • si5351a_set_clock_input_source - Procedure
  • si5351a_set_clock_output_inverted - Procedure
  • si5351a_set_clock_output_not_inverted - Procedure
  • si5351a_set_crystal_load_capacitance - Procedure
  • si5351a_set_force_feedback_a_multisynth_fractional_mode - Procedure
  • si5351a_set_force_feedback_a_multisynth_integer_mode - Procedure
  • si5351a_set_force_feedback_b_multisynth_fractional_mode - Procedure
  • si5351a_set_force_feedback_b_multisynth_integer_mode - Procedure
  • si5351a_set_frequency - Function returns bit
  • si5351a_set_frequency_manual - Function returns bit
  • si5351a_set_frequency_on_pll - Function returns bit
  • si5351a_set_initial_phase_offset - Procedure
  • si5351a_set_multisynth_fractional_mode - Procedure
  • si5351a_set_multisynth_integer_mode - Procedure
  • si5351a_set_multisynth_source_pll_a - Procedure
  • si5351a_set_multisynth_source_pll_b - Procedure
  • si5361a_print_clock_settings - Procedure


si5351a_crystal_signal_is_valid - JALlib Procedures Help

si5351a_crystal_signal_is_valid JALLIB FUNCTION

Signature

function si5351a_crystal_signal_is_valid() return bit is

Description

Returns TRUE when a valid crystal signal is detected.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_disable_clock_output - JALlib Procedures Help

si5351a_disable_clock_output JALLIB PROCEDURE

Signature

procedure si5351a_disable_clock_output(byte in clock) is

Description

Disable the given clock output. Parameter clock must be in range
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. The level of the output signal depends on
the set clock disable state as defined by si5351a_set_clock_disable_state().

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_enable_clock_output - JALlib Procedures Help

si5351a_enable_clock_output JALLIB PROCEDURE

Signature

procedure si5351a_enable_clock_output(byte in clock) is

Description

Enable the given clock output. Parameter clock must be in range
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_get_revision_id - JALlib Procedures Help

si5351a_get_revision_id JALLIB FUNCTION

Signature

function si5351a_get_revision_id() return byte is

Description

Returns the revision id of the device.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_init - JALlib Procedures Help

si5351a_init JALLIB PROCEDURE

Signature

procedure si5351a_init() is

Description

Initialize the IIC interface and the Si5351a device.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

None

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_pll_a_is_locked - JALlib Procedures Help

si5351a_pll_a_is_locked JALLIB FUNCTION

Signature

function si5351a_pll_a_is_locked() return bit is

Description

Returns TRUE when PLL A is locked.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_pll_b_is_locked - JALlib Procedures Help

si5351a_pll_b_is_locked JALLIB FUNCTION

Signature

function si5351a_pll_b_is_locked() return bit is

Description

Returns TRUE when PLL B is locked.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_power_down_clock_output - JALlib Procedures Help

si5351a_power_down_clock_output JALLIB PROCEDURE

Signature

procedure si5351a_power_down_clock_output(byte in clock) is

Description

Power down given clock output. Parameter clock must be in range
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_power_up_clock_output - JALlib Procedures Help

si5351a_power_up_clock_output JALLIB PROCEDURE

Signature

procedure si5351a_power_up_clock_output(byte in clock) is

Description

Power up given clock output. Parameter clock must be in range
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_clock_disable_state - JALlib Procedures Help

si5351a_set_clock_disable_state JALLIB PROCEDURE

Signature

procedure si5351a_set_clock_disable_state(byte in clock, byte in disable_state) is

Description

Set the clock disable state Parameter clock must be between
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. Disable state must be one of the four
values of SI5351A_CLOCK_DISABLE_STATE

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in
  • disable_state - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_clock_drive_strength - JALlib Procedures Help

si5351a_set_clock_drive_strength JALLIB PROCEDURE

Signature

procedure si5351a_set_clock_drive_strength(byte in clock, byte in strength) is

Description

Set the multisynth as clock input source. Parameter clock must be between
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7. Drive strength must be one of the four
values of SI5351A_CLOCK_DRIVE_X_MA (X = 2,4,6 or 8)

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in
  • strength - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_clock_output_inverted - JALlib Procedures Help

si5351a_set_clock_output_inverted JALLIB PROCEDURE

Signature

procedure si5351a_set_clock_output_inverted(byte in clock) is

Description

Set the clock output to inverted. Parameter clock must be in range
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_clock_output_not_inverted - JALlib Procedures Help

si5351a_set_clock_output_not_inverted JALLIB PROCEDURE

Signature

procedure si5351a_set_clock_output_not_inverted(byte in clock) is

Description

Set the clock output to not inverted. Parameter clock must be in range
SI5351A_CLOCK_0 .. SI5351A_CLOCK_7.

Include

To use this procedure, include the library:

include si5351a

Parameters

  • clock - byte in

Return Value

None

Example

From sample file: 16f18857_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock
--        generator using a menu structure.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main features of the Si5351a library
--
-- Sources:
--
-- Notes:
--
include 16f18857

-- Use a 20 MHz  crystal.
pragma target clock 20_000_000      -- oscillator frequency

pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C7_direction  -- Pin 18 for 28 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 17 for 28 pin DIP.
const serial_hw_baudrate = 115200
include serial_hardware
serial_hw_init()
include print
include strings

-- IIC pin definitions for this chip.
alias si5351a_scl is pin_C3 -- Pin 14 for 28 pin DIP
alias si5351a_scl_direction is pin_C3_direction
alias si5351a_sda is pin_C4 -- Pin 15 for 28 pin DIP.
alias si5351a_sda_direction is pin_C4_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

-- We need to re-assign the pins to their default value.
include pps
pps_control_lock(FALSE)
RC6PPS = PPS_TX    -- TX1 re-assigned to C6  (default)
RXPPS  = PPS_RC7   -- C7 re-assigned to RX1  (default)
if !defined(SI5351A_SOFTWARE_IIC) then
   -- Do not remap pins otherwise software IIC does not work.
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
end if
pps_control_lock(TRUE)

include si5351a
si5351a_init()

-- Max length of input string.
const byte MAX_INPUT = 35

-- Global variables
var byte input_string[MAX_INPUT]
var byte command, parameter_count, input_length
var dword parameter_1
var dword parameter_2
var dword parameter_3
var dword parameter_4
var bit function_executed, give_info

-- -----------------------  Functions and Procedures ---------------------------

procedure show_menu() is
   print_crlf(serial_hw_data)
   print_string(serial_hw_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw_data,"Note that spaces are required between command and parameters.\r\n")
   print_string(serial_hw_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw_data,"0  No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw_data,"1  Set frequency on clock output. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   Example: 1 20000000 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"2  Set frequency on clock output and on PLL. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 2 20000000 1 1<CR><LF>.\r\n")
   print_string(serial_hw_data,"3  Set frequency manual. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Frequency> = Clock frequency in Hz, range 2500..225000000.\r\n")
   print_string(serial_hw_data,"   <PLL Frequency> = PLL frequency given in Hz, range 600000000..900000000.\r\n")
   print_string(serial_hw_data,"   <Clock Output> = Clock output in range 0..7.\r\n")
   print_string(serial_hw_data,"   <PLL> = PLL to use, select 0 for PLL A or 1 for PLL B.\r\n")
   print_string(serial_hw_data,"   Example: 3 10000000 600000000 2 0<CR><LF>.\r\n")
   print_string(serial_hw_data,"4  Enable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"5  Disable clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"6  Power up clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"7  Power down clock output. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"8  Set clock output inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"9  Set clock output not inverted. Parameter: <Clock Output> in range 0..7.\r\n")
   print_string(serial_hw_data,"10 Set clock drive strength. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <Strength> in range 0..3 (see definition).\r\n")
   print_string(serial_hw_data,"11 Set clock disable state. Parameters:\r\n")
   print_string(serial_hw_data,"   <Clock Output> in range 0..7, <State> in range 0..3 (see definition).\r\n")
   print_crlf(serial_hw_data)
end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return byte is
   var byte data, counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw_read(data) then
         if (data == 0x0D) then
            cr_received = TRUE
         elsif (data == 0x0A) then
            lf_received = TRUE
         else
            input_string[counter] = data
         end if
         counter = counter + 1
      end if
   end loop

   return counter

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input(byte in length) is
   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed
   var bit parameter_3_processed, parameter_4_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_count = 0
   parameter_1 = 0
   parameter_2 = 0
   parameter_3 = 0
   parameter_4 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   parameter_3_processed = FALSE
   parameter_4_processed = FALSE
   while (counter < length) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrect the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = string_to_dword(processed_string)
            parameter_1_processed = TRUE
            parameter_count = 1
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = string_to_dword(processed_string)
            parameter_2_processed = TRUE
            parameter_count = 2
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_3_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_3 = string_to_dword(processed_string)
            parameter_3_processed = TRUE
            parameter_count = 3
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_4_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_4 = word(string_to_dword(processed_string))
            parameter_4_processed = TRUE
            parameter_count = 4
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command(bit out executed) return bit is

   var bit ok

   ok = TRUE
   executed = TRUE
   case command of

      0: -- No command, show menu.
      block
         show_menu()
      end block

      1: -- Set frequency on clock output. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_count == 2) then
            executed = si5351a_set_frequency(parameter_1, byte(parameter_2))
         else
            ok = FALSE
         end if
      end block

      2: -- Set frequency on clock output and on PLL. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 <= SI5351A_CLOCK_7) &
            (parameter_3 <= SI5351A_PLL_B) &
            (parameter_count == 3) then
            executed = si5351a_set_frequency_on_pll(parameter_1, byte(parameter_2),
                       byte(parameter_3))
         else
            ok = FALSE
         end if
      end block

      3: -- Set frequency manual. Check parameters.
      block
         if (parameter_1 >= SI5351A_MIN_OUT_FREQUENCY) &
            (parameter_1 <= SI5351A_MAX_OUT_FREQUENCY) &
            (parameter_2 >= SI5351A_MIN_PLL_FREQUENCY) &
            (parameter_2 <= SI5351A_MAX_PLL_FREQUENCY) &
            (parameter_3 <= SI5351A_CLOCK_7) &
            (parameter_4 <= SI5351A_PLL_B) &
            (parameter_count == 4) then
            executed = si5351a_set_frequency_manual(parameter_1, parameter_2,
                       byte(parameter_3), byte(parameter_4))
         else
            ok = FALSE
         end if
      end block

      4: -- Enable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_enable_clock_output(byte(parameter_1))
         else
            ok = FALSE
         end if
      end block

      5: -- Disable clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_disable_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      6: -- Power up clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_up_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      7: -- Power down clock output. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_power_down_clock_output(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      8: -- Set clock output inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      9: -- Set clock output not inverted. Check parameter.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_count == 1) then
           si5351a_set_clock_output_not_inverted(byte(parameter_1))
        else
            ok = FALSE
         end if
      end block

      10: -- Set clock drive strength. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DRIVE_8_MA) &
            (parameter_count == 2) then
            si5351a_set_clock_drive_strength(byte(parameter_1),
                                             byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      11: -- Set clock disable state. Check parameters.
      block
         if (parameter_1 <= SI5351A_CLOCK_7) &
            (parameter_2 <= SI5351A_CLOCK_DISABLE_STATE_NEVER) &
            (parameter_count == 2) then
            si5351a_set_clock_disable_state(byte(parameter_1),
                                            byte(parameter_2))
        else
            ok = FALSE
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-- -----------------------  Main program starts here ---------------------------

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")
give_info = TRUE

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   input_length = get_input()
   if input_length > 0 then
      process_input(input_length)
      if execute_command(function_executed) then
         -- Command was OK but check if the function was executed.
         if function_executed then
            print_string(serial_hw_data,"Command and function executed succesfully!\r\n\r\n")
         else
            print_string(serial_hw_data,"Command OK but function could not be executed!\r\n\r\n")
         end if
      else
         print_string(serial_hw_data,"Invalid command!\r\n\r\n")
      end if
      -- Show any updated info.
      give_info = TRUE
   else
      print_string(serial_hw_data,"Input too long!\r\n\r\n")
   end if

   -- Report new info if needed.
   if give_info then
      give_info = FALSE
      print_status_info()
      if defined(SI5351A_DEBUG) then
         -- Some extra info about the setttings
         si5361a_print_clock_settings()
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_frequency - JALlib Procedures Help

si5351a_set_frequency JALLIB FUNCTION

Signature

function si5351a_set_frequency(dword in frequency, byte in clock) return bit is

Description

Set the given frequency on the given clock output. The frequency is given
in Hz. Clock must be in range I5351A_CLOCK_0 .. SI5351A_CLOCK_7.
This function selects the PLL automatically and tries to map the clocks as
much as possible on the same PLL as to enable multiple frequencies on
different clock outputs. The function returns TRUE when the frequency was set
succesfully on the given clock output.
Note that this function requires much more ROM code for mapping more clocks
on the same PLL so if you do not need the feature use the function
'si5351a_set_frequency_manual' to limit ROM space.

Include

To use this procedure, include the library:

include si5351a

Parameters

  • frequency - dword in
  • clock - byte in

Return Value

bit - Function return value

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_frequency_manual - JALlib Procedures Help

si5351a_set_frequency_manual JALLIB FUNCTION

Signature

function si5351a_set_frequency_manual(dword in frequency,

Description

Set the given frequency with the given PLL frequency on the given clock
output using the given PLL. The clock frequency and PLL frequency are given in Hz.
Clock must be in range I5351A_CLOCK_0 .. SI5351A_CLOCK_7. If 'pll' is
SI5351A_PLL_A then PLL A is used, if SI5351A_PLL_B then PLL B is used.
It is possible to set multiple outputs on different frequencies using the same
pll as long as the pll frequency is the same for these outputs.
Important: For frequencies below 150 MHz pll_frequency must be a multiple
of the crystal frequency. For frequencies higher than 150 MHz the pll_frequency
must be exactly 4 times the frequency.
The function returns TRUE when the frequency was set succesfully.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

None

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5351a_set_frequency_on_pll - JALlib Procedures Help

si5351a_set_frequency_on_pll JALLIB FUNCTION

Signature

function si5351a_set_frequency_on_pll(dword in frequency, byte in clock,

Description

Set the given frequency on the given clock output using the given PLL.
The frequency is given in Hz. Clock must be in range I5351A_CLOCK_0 ..
SI5351A_CLOCK_7. If 'pll' is SI5351A_PLL_A then PLL A is used, if
SI5351A_PLL_B then PLL B is used.
It is possible to set multiple outputs on different frequencies using the same
pll as long as the pll frequency is the same for these outputs.
The function returns TRUE when the frequency was set succesfully.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

None

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


si5361a_print_clock_settings - JALlib Procedures Help

si5361a_print_clock_settings JALLIB PROCEDURE

Signature

procedure si5361a_print_clock_settings() is

Description

Print the set frequencies and the assigned PLL per clock output. Can be used
for testing purposes.

Include

To use this procedure, include the library:

include si5351a

Parameters

None

Return Value

None

Example

From sample file: 16f1825_si5351a.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the Si5351a programmable any frequency clock generator.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020 all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Shows the main clock features of the Si5351a library.
--
-- Sources:
--
-- Notes:
--
include 16f1825

pragma warn all no
pragma opt variable_reduce yes

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      DISABLED        -- No low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()
_usec_delay(100_000)

-- Serial hardware pin aliases.
alias pin_RX_direction  is pin_C5_direction  -- Pin 5 for 14 pin DIP.
alias pin_TX_direction  is pin_C4_direction  -- Pin 6 for 14 pin DIP.
const serial_hw_baudrate = 115_200
include serial_hardware
include print
serial_hw_init()

-- IIC pin definitions
alias si5351a_scl is pin_C0 -- Pin 10 for 14 pin DIP
alias si5351a_scl_direction is pin_C0_direction
alias si5351a_sda is pin_C1 -- Pin 9 for 14 pin DIP.
alias si5351a_sda_direction is pin_C1_direction

-- We do not use the software IIC but the default hardware IIC.
-- const SI5351A_SOFTWARE_IIC = TRUE
-- Use the debugging info if you want more info about what has been set.
-- const SI5351A_DEBUG = TRUE

include si5351a
si5351a_init()

const dword INIT_FREQUENCY_1 = 10_000_000
const dword INIT_FREQUENCY_2 = 1_000_000
const dword INIT_FREQUENCY_3 = 2_500

var dword frequency_1
var dword frequency_2
var dword frequency_3
var dword pll_frequency

-- Wait for some time.
procedure wait_some_time() is
   _usec_delay(1_000_000)
end procedure

-- Print some status info of the Si5351a
procedure print_status_info() is

   print_crlf(serial_hw_data)
   if si5351a_pll_a_is_locked() then
      print_string(serial_hw_data,"PLL A is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL A is not locked.\r\n")
   end if

   if si5351a_pll_b_is_locked() then
      print_string(serial_hw_data,"PLL B is locked.\r\n")
   else
      print_string(serial_hw_data,"PLL B is not locked.\r\n")
   end if

   if si5351a_crystal_signal_is_valid() then
      print_string(serial_hw_data,"Cyrstal signal is valid.\r\n")
   else
      print_string(serial_hw_data,"Cyrstal signal is not valid.\r\n")
   end if

   print_string(serial_hw_data,"Revision id is: ")
   print_byte_dec(serial_hw_data, si5351a_get_revision_id())

   print_crlf(serial_hw_data)

end procedure

-------------------------- Main program starts here ----------------------------

frequency_1 = INIT_FREQUENCY_1
frequency_2 = INIT_FREQUENCY_2
frequency_3 = INIT_FREQUENCY_3
pll_frequency = 900_000_000

print_string(serial_hw_data,"Sample program for the Si5351 clock generator.\r\n")

forever loop

   -- We use the three available functions to set the frequencies. Note that
   -- two of them require quite some ROM space.

   -- Set the frequency manual. This function uses the least ROM space.
   if si5351a_set_frequency_manual(frequency_1, pll_frequency, SI5351A_CLOCK_0,
                                   SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_1)
       print_string(serial_hw_data," on clock 0 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is a variant of the one above.
    if si5351a_set_frequency_on_pll(frequency_2, SI5351A_CLOCK_1, SI5351A_PLL_B) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_2)
       print_string(serial_hw_data," on clock 1 not set!")
       print_crlf(serial_hw_data)
   end if

    -- This is the most advanced function but also the most expensive in ROM size.
    if si5351a_set_frequency(frequency_3, SI5351A_CLOCK_2) then
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 set!")
       print_crlf(serial_hw_data)
   else
       print_string(serial_hw_data,"Frequency: ")
       print_dword_dec(serial_hw_data, frequency_3)
       print_string(serial_hw_data," on clock 2 not set!")
       print_crlf(serial_hw_data)
   end if

   print_crlf(serial_hw_data)

   -- Increase the frequencies.
   frequency_1 = frequency_1 + 100_000
   frequency_2 = frequency_2 + 50_000
   frequency_3 = frequency_3 + 1_000

   if (frequency_1 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_1 = INIT_FREQUENCY_1
   end if

   if (frequency_2 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_2 = INIT_FREQUENCY_2
   end if

   if (frequency_3 > SI5351A_MAX_OUT_FREQUENCY) then
      frequency_3 = INIT_FREQUENCY_3
   end if

   -- Some debug info, if enabled.
   if defined(SI5351A_DEBUG) then
      print_status_info()
      si5361a_print_clock_settings()
   end if

   wait_some_time()

end loop

Generated by JALlib CHM Help System | Source: si5351a.jal


sign8 - JALlib Procedures Help

sign8 JALLIB FUNCTION

Signature

function sign8(sbyte in x) return sbyte is

Description

Title: Obtain sign of a signed 8-bits integer
Arguments: signed 8-bits integer
Returns: signed 8-bits integer
-1 : negative
0 : zero
+1 : positive
Original: Eur van Andel

Include

To use this procedure, include the library:

include math

Parameters

  • x - sbyte in

Return Value

None

Example

From sample file: 18f2685_math.jal

-- Title: sample for math.jal, showing use of abs() and sign() functions
-- Author: Eur van Andel Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: shows 3 signed variables which can be incremented and decremented
-- and the result of the abs() and sign() functions on these variables.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

include 18f2685
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = 0b_0             -- no watchdog

enable_digital_io()              -- no analog functions used

-- pick one of the following LCD connections:

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20

var bit lcd_sterm_pin is pin_a0     -- Sterm LCD & keyboard \
var bit lcd_sterm_pin_dir is pin_a0_direction   --               >  single pin LCD & keyboard connection
include lcd_sterm_master      -- library for LCD and keyboard   /   this has PIC inside as well

-- alias LCD_RS           is pin_b5       -- LCD command/data select       \
-- alias LCD_EN           is pin_b4       -- LCD data trigger               \
-- alias LCD_dataport     is portb_low    -- LCD data nibble                 > traditional 6 pin LCD connection
-- portb_direction        = all_output    -- LCD data is portb_low          /
-- include lcd_hd44780_4                  -- LCD library with 4 data lines /
-- lcd_init()

include math                              -- duh
include print                             -- nice formatted output

var sbyte  x = 3
var sword  y = -3
var sdword z = 5

procedure keyboard() is

   if getkey() == 1 then  x = x + 1    end if  -- manual override
   if getkey() == 4 then  x = x - 1    end if

   if getkey() == 2 then  y = y + 1    end if
   if getkey() == 5 then  y = y -1     end if

   if getkey() == 3 then  z = z + 1    end if
   if getkey() == 6 then  z = z -1     end if

   if getkey() == 7 then         end if
   if getkey() == 0x0A then      end if

   if getkey() == 8 then      end if

   if getkey() == 0x0F then      end if
   if getkey() == 0x0E then      end if

   if getkey() == 9 then         end if
   if getkey() == 0x0D then      end if

   if getkey() == 0x0B then      end if
   if getkey() == 0 then         end if
   if getkey() == 0x0C then      end if

end procedure

-- START MAIN

delay_100ms(5)
lcd_clear_screen
delay_100ms(5)
lcd_clear_screen

--                 12345678901234567890
const byte str0[]="math demo sample    "  -- print banner
const byte str1[]="abs() and sign()    "
const byte str2[]="use keys 1..6       "

lcd_cursor_position(0,0)
print_string(lcd, str0)
lcd_cursor_position(1,0)
print_string(lcd, str1)

delay_1s(5)

lcd_clear_screen

forever loop

   lcd_cursor_position(0,0)
   lcd = "x" lcd = "="lcd = " "
   print_sbyte_dec(lcd, x)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_byte_dec(lcd, abs8(x))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign8(x))
   if x < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(1,0)
   lcd = "y" lcd = "="lcd = " "
   print_sword_dec(lcd, y)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_word_dec(lcd, abs16(y))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign16(y))
   if y < 10 & x > 0 then
      lcd = " "                  -- cleaning junk from LCD
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(2,0)
   lcd = "z" lcd = "="lcd = " "
   print_sdword_dec(lcd, z)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_dword_dec(lcd, abs32(z))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign32(z))
   lcd = " "
   if z < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(3,0)
   print_string(lcd, str2)

   delay_1ms(200)   -- proper LCD refresh rate

   keyboard()

end loop

Generated by JALlib CHM Help System | Source: math.jal


sign16 - JALlib Procedures Help

sign16 JALLIB FUNCTION

Signature

function sign16(sword in x) return sbyte is

Description

Title: Obtain sign of a signed 16-bits integer
Arguments: signed 8-bits integer
Returns: signed 16-bits integer
-1 : negative
0 : zero
+1 : positive
Original: Eur van Andel

Include

To use this procedure, include the library:

include math

Parameters

  • x - sword in

Return Value

None

Example

From sample file: 18f2685_math.jal

-- Title: sample for math.jal, showing use of abs() and sign() functions
-- Author: Eur van Andel Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: shows 3 signed variables which can be incremented and decremented
-- and the result of the abs() and sign() functions on these variables.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

include 18f2685
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = 0b_0             -- no watchdog

enable_digital_io()              -- no analog functions used

-- pick one of the following LCD connections:

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20

var bit lcd_sterm_pin is pin_a0     -- Sterm LCD & keyboard \
var bit lcd_sterm_pin_dir is pin_a0_direction   --               >  single pin LCD & keyboard connection
include lcd_sterm_master      -- library for LCD and keyboard   /   this has PIC inside as well

-- alias LCD_RS           is pin_b5       -- LCD command/data select       \
-- alias LCD_EN           is pin_b4       -- LCD data trigger               \
-- alias LCD_dataport     is portb_low    -- LCD data nibble                 > traditional 6 pin LCD connection
-- portb_direction        = all_output    -- LCD data is portb_low          /
-- include lcd_hd44780_4                  -- LCD library with 4 data lines /
-- lcd_init()

include math                              -- duh
include print                             -- nice formatted output

var sbyte  x = 3
var sword  y = -3
var sdword z = 5

procedure keyboard() is

   if getkey() == 1 then  x = x + 1    end if  -- manual override
   if getkey() == 4 then  x = x - 1    end if

   if getkey() == 2 then  y = y + 1    end if
   if getkey() == 5 then  y = y -1     end if

   if getkey() == 3 then  z = z + 1    end if
   if getkey() == 6 then  z = z -1     end if

   if getkey() == 7 then         end if
   if getkey() == 0x0A then      end if

   if getkey() == 8 then      end if

   if getkey() == 0x0F then      end if
   if getkey() == 0x0E then      end if

   if getkey() == 9 then         end if
   if getkey() == 0x0D then      end if

   if getkey() == 0x0B then      end if
   if getkey() == 0 then         end if
   if getkey() == 0x0C then      end if

end procedure

-- START MAIN

delay_100ms(5)
lcd_clear_screen
delay_100ms(5)
lcd_clear_screen

--                 12345678901234567890
const byte str0[]="math demo sample    "  -- print banner
const byte str1[]="abs() and sign()    "
const byte str2[]="use keys 1..6       "

lcd_cursor_position(0,0)
print_string(lcd, str0)
lcd_cursor_position(1,0)
print_string(lcd, str1)

delay_1s(5)

lcd_clear_screen

forever loop

   lcd_cursor_position(0,0)
   lcd = "x" lcd = "="lcd = " "
   print_sbyte_dec(lcd, x)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_byte_dec(lcd, abs8(x))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign8(x))
   if x < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(1,0)
   lcd = "y" lcd = "="lcd = " "
   print_sword_dec(lcd, y)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_word_dec(lcd, abs16(y))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign16(y))
   if y < 10 & x > 0 then
      lcd = " "                  -- cleaning junk from LCD
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(2,0)
   lcd = "z" lcd = "="lcd = " "
   print_sdword_dec(lcd, z)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_dword_dec(lcd, abs32(z))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign32(z))
   lcd = " "
   if z < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(3,0)
   print_string(lcd, str2)

   delay_1ms(200)   -- proper LCD refresh rate

   keyboard()

end loop

Generated by JALlib CHM Help System | Source: math.jal


sign32 - JALlib Procedures Help

sign32 JALLIB FUNCTION

Signature

function sign32(sdword in x) return sbyte is

Description

Title: Obtain sign of a signed 32-bits integer
Arguments: signed 32-bits integer
Returns: signed 8-bits integer
-1 : negative
0 : zero
+1 : positive
Original: Eur van Andel

Include

To use this procedure, include the library:

include math

Parameters

  • x - sdword in

Return Value

None

Example

From sample file: 18f2685_math.jal

-- Title: sample for math.jal, showing use of abs() and sign() functions
-- Author: Eur van Andel Copyright (c) 2010, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4m
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: shows 3 signed variables which can be incremented and decremented
-- and the result of the abs() and sign() functions on these variables.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

include 18f2685
pragma target clock 20_000_000
pragma target OSC  HS
pragma target XINST disabled
pragma target WDT  control
pragma target LVP  enabled
pragma target MCLR external

WDTCON_SWDTEN = 0b_0             -- no watchdog

enable_digital_io()              -- no analog functions used

-- pick one of the following LCD connections:

const byte LCD_ROWS = 4          -- Sterm LCD + keyboard on single pin_a4
const byte LCD_CHARS = 20

var bit lcd_sterm_pin is pin_a0     -- Sterm LCD & keyboard \
var bit lcd_sterm_pin_dir is pin_a0_direction   --               >  single pin LCD & keyboard connection
include lcd_sterm_master      -- library for LCD and keyboard   /   this has PIC inside as well

-- alias LCD_RS           is pin_b5       -- LCD command/data select       \
-- alias LCD_EN           is pin_b4       -- LCD data trigger               \
-- alias LCD_dataport     is portb_low    -- LCD data nibble                 > traditional 6 pin LCD connection
-- portb_direction        = all_output    -- LCD data is portb_low          /
-- include lcd_hd44780_4                  -- LCD library with 4 data lines /
-- lcd_init()

include math                              -- duh
include print                             -- nice formatted output

var sbyte  x = 3
var sword  y = -3
var sdword z = 5

procedure keyboard() is

   if getkey() == 1 then  x = x + 1    end if  -- manual override
   if getkey() == 4 then  x = x - 1    end if

   if getkey() == 2 then  y = y + 1    end if
   if getkey() == 5 then  y = y -1     end if

   if getkey() == 3 then  z = z + 1    end if
   if getkey() == 6 then  z = z -1     end if

   if getkey() == 7 then         end if
   if getkey() == 0x0A then      end if

   if getkey() == 8 then      end if

   if getkey() == 0x0F then      end if
   if getkey() == 0x0E then      end if

   if getkey() == 9 then         end if
   if getkey() == 0x0D then      end if

   if getkey() == 0x0B then      end if
   if getkey() == 0 then         end if
   if getkey() == 0x0C then      end if

end procedure

-- START MAIN

delay_100ms(5)
lcd_clear_screen
delay_100ms(5)
lcd_clear_screen

--                 12345678901234567890
const byte str0[]="math demo sample    "  -- print banner
const byte str1[]="abs() and sign()    "
const byte str2[]="use keys 1..6       "

lcd_cursor_position(0,0)
print_string(lcd, str0)
lcd_cursor_position(1,0)
print_string(lcd, str1)

delay_1s(5)

lcd_clear_screen

forever loop

   lcd_cursor_position(0,0)
   lcd = "x" lcd = "="lcd = " "
   print_sbyte_dec(lcd, x)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_byte_dec(lcd, abs8(x))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign8(x))
   if x < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(1,0)
   lcd = "y" lcd = "="lcd = " "
   print_sword_dec(lcd, y)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_word_dec(lcd, abs16(y))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign16(y))
   if y < 10 & x > 0 then
      lcd = " "                  -- cleaning junk from LCD
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(2,0)
   lcd = "z" lcd = "="lcd = " "
   print_sdword_dec(lcd, z)
   lcd = " "
   lcd = "a" lcd = "b" lcd = "s"
   lcd = " "
   print_dword_dec(lcd, abs32(z))
   lcd = " "
   lcd = "s" lcd = "i" lcd = "g" lcd = "n"
   lcd = " "
   print_sbyte_dec(lcd, sign32(z))
   lcd = " "
   if z < 10 & x > 0 then
      lcd = " "
      lcd = " "
   else
      lcd = " "
   end if

   lcd_cursor_position(3,0)
   print_string(lcd, str2)

   delay_1ms(200)   -- proper LCD refresh rate

   keyboard()

end loop

Generated by JALlib CHM Help System | Source: math.jal


sirc.jal - JALLIB Library Documentation

sirc.jal JALLIB LIBRARY

Title

SIRC library for decoding and encoding SIRC protocol

Author

Mike Reynolds, Copyright (C) 2009, all rights reserved.

Compiler

>=2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides functions for sending and receiving SIRC
infrared remote control codes
--
SIRC infrared remote control codes
SIRC is widely used protocol for consumer entertainment devices
such as TV's, VCR's, DVD players, Hi-Fi receivers, etc
SIRC is found in 12-bit, 15-bit, 20- bit versions
This decoder is for the 12-bit version
--
12-bit SIRC is comprised of a pulse-width modulated bit stream
with 5 address bits and 7 data bits. A logical 1 is represented
by a 1.2 mS burst of the 40 khz carrier, whereas a logical 0
is represented by a 0.6 mS burst of the carrier.
--
The data stream is preceeded by a start burst 2.4 mS in duration
of the 40 khz carrier and then the data is sent LSB first with the
command preceeding the address. Commands are repeated every 45 mS
(measured from start to start) as long as the button is pressed.

Notes

--
**************************************************************************
**************************************************************************
***** *****
***** In your user code you must define whether you are building *****
***** a transmitter or receiver so that the correct procedures *****
***** will be included . *****
***** *****
***** To define a transmitter: *****
***** const SIRC_transmitter = 1 *****
***** const SIRC_receiver = 0 *****
***** *****
***** To define a receiver: *****
***** const SIRC_receiver = 1 *****
***** const SIRC_transmitter = 0 *****
***** You must declare either an input or output pin and direction *****
***** such as var bit sirc_pulse_in is pin_B0 *****
***** or var bit IR_pulse_out is pin_B1 *****
***** *****
**************************************************************************
**************************************************************************
--
Some example Device and Command codes
Device ID Code
1 TV
2 VTR1
4 VTR2
6 laserdisk
7 VTR2
11 VTR3
12 Surround Sound Processor
18 Equalizer
16 Cassette Deck and Tuner
17 CD Player
164 TV digital effects (note 8 bit device code)
--
Commnad (Button) Codes for TV
value function value function
000 1 button 021 Power
001 2 button 022 Reset TV
002 3 button 023 Audio Mode:Mono/SAP/Stereo
003 4 button 024 Picture up
004 5 button 025 Picture down
005 6 button 026 Color up
006 7 button 027 Color down
007 8 button 030 Brightness up
008 9 button 031 Brightness down
009 10 button/0 button 032 Hue up
011 Enter 033 Hue down
016 channel up 034 Sharpness up
017 channel down 035 Sharpness down
018 volume up 036 Select TV tuner
019 volume down 038 Balance Left
020 Mute 039 Balance Right
--
041 Surround on/off 094 PIP position
042 Aux/Ant 095 PIP swap
047 Power off 096 Guide
048 Time display 097 Video setup
054 Sleep Timer 098 Audio setup
058 Channel Display 099 Exit setup
059 Channel jump 107 Auto Program
064 Select Input Video1 112 Treble up
065 Select Input Video2 113 Treble down
066 Select Input Video3 114 Bass up
074 Noise Reduction on/off 115 Bass down
078 Cable/Broadcast 116 + key

Sources

http://www.sbprojects.com/knowledge/ir/sirc.htm
http://www.ustr.net/infrared/sony.shtml
http://web.archive.org/web/20071212170236/http://www.geocities.com/CapeCanaveral/Launchpad/4652/sircs.htm


sirc_rx.jal - JALLIB Library Documentation

sirc_rx.jal JALLIB LIBRARY

Title

SIRC receiver library for decoding SIRC protocol

Author

Mike Reynolds, Copyright (C) 2009, all rights reserved.

Compiler

>=2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides functions for receiving SIRC
infrared remote control codes. See sirc.jal for more info.

Notes

See sirc.jal for more info.

Sources

http://www.sbprojects.com/knowledge/ir/sirc.htm
http://www.ustr.net/infrared/sony.shtml
http://web.archive.org/web/20071212170236/http://www.geocities.com/CapeCanaveral/Launchpad/4652/sircs.htm

Routines

  • get_sirc - Procedure


sirc_tx.jal - JALLIB Library Documentation

sirc_tx.jal JALLIB LIBRARY

Title

SIRC transmitter library for encoding SIRC protocol

Author

Mike Reynolds, Copyright (C) 2009, all rights reserved.

Compiler

>=2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

this library provides functions for sending SIRC
infrared remote control codes. See sirc.jal for more info.

Notes

See sirc.jal for more info.

dependant Procedures for Send_SIRC

Sources

http://www.sbprojects.com/knowledge/ir/sirc.htm
http://www.ustr.net/infrared/sony.shtml
http://web.archive.org/web/20071212170236/http://www.geocities.com/CapeCanaveral/Launchpad/4652/sircs.htm

Routines

  • fast_ir_pulse_0 - Procedure
  • fast_ir_pulse_1 - Procedure
  • fast_ir_pulse_start - Procedure
  • ir_pulse_deadtime - Procedure
  • send_sirc - Procedure
  • slow_ir_pulse_0 - Procedure
  • slow_ir_pulse_1 - Procedure
  • slow_ir_pulse_start - Procedure


slip.jal - JALLIB Library Documentation

slip.jal JALLIB LIBRARY

Title

Library for SLIP (Serial Line IP)

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library sends and receives SLIP (Serial Line IP) packets
for communication with serial data in packet form.

Sources

http://tools.ietf.org/html/rfc1055

SLIP special character codes

Constants and Variables

SLIP_BYTE_WIDTH - const byte = 1
SLIP_BYTE_WIDTH - const byte = 2

Routines

  • slip_end_packet - Procedure
  • slip_init - Procedure
  • slip_packet_available'get - Function returns bit
  • slip_poll - Procedure
  • slip_send_data - Procedure
  • slip_serial_hw_isr - Procedure


slip_end_packet - JALlib Procedures Help

slip_end_packet JALLIB PROCEDURE

Signature

procedure slip_end_packet() is

Description

Sends end of packet data

Include

To use this procedure, include the library:

include slip

Parameters

None

Return Value

None

Example

From sample file: 18f4525_slip_poll.jal

-- Title: Sample for SLIP (Serial Line IP)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample sends and receives SLIP (Serial Line IP) packets
--              for communication with serial data in packet form. This sample
--              will receive packets via poll method. You must continuously
--              poll the slip_poll() procedure.
--
-- Sources:
-- http://tools.ietf.org/html/rfc1055
--
-- Notes:
-- 1. The program will send hex 01 02 03 C0 05 06 DB 08 09 0A through SLIP which
--    will be encoded into slip format then sent via the serial port.
--    If you have your PC serial port connected, you will get this hex data:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0
-- 2. Now send back an encoded message:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0 (same as above).
--    SLIP will decode the data and echo back your original message:
--    01 02 03 C0 05 06 DB 08 09 0A
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SLIP
const word SLIP_MTU = 10  -- Max bytes per packet (Max Transfer Unit)
--
-- choose your interrupt routine. you may ignore this and create your own
-- isr or use polling method slip_poll()
const bit SLIP_USE_SERIAL_HW_ISR = FALSE -- TRUE = receive data via serial hw interrupt
--
-- choose your data carrier
alias slip_serial_data is serial_data
alias slip_data_available is serial_data_available
--
-- Choose the size of your receive buffer.
-- Should be the same as SLIP MTU if slip interrupts are not enabled
const byte QUEUE01_SIZE = SLIP_MTU
include queue01 -- include the queue/buffer library
alias slip_rx_buffer is queue01_nb  -- alias buffer for received data
--
-- Choose buffer to hold packet sizes
const byte QUEUE02_SIZE = 10
include queue02 -- include the queue/buffer library
alias slip_packet_size_buffer is queue02_nb     -- alias buffer for packet sizes
alias slip_packets_available is queue02_nr_used -- alias for number of packets avail
--
-- callback for when a full slip packet is received (not required for isr)
procedure slip_received_packet_callback() -- prototype
--
include slip -- include the library
--
slip_init() -- init the slip library

-- main program --

-- send some junk to ensure serial port is working
for 4 loop
   serial_data = 0
end loop

-- Send some data to the serial port in slip packet form
const byte test_data[SLIP_MTU] = {0x01,0x02,0x03,0xC0,0x05,0x06,0xDB,0x08,0x09,0x0A}
var byte count1 = 0
for SLIP_MTU loop                    -- loop through all bytes in packet
   slip_send_data(test_data[count1]) -- send slip packet data via serial port
   count1 = count1 + 1
end loop
-- if you don't send SLIP_MTU bytes, then you
-- must call slip_end_packet()
;slip_end_packet()

-- callback for when a full slip packet is received
procedure slip_received_packet_callback() is
   -- get the packet size
   var byte packet_size = slip_packet_size_buffer
   if packet_size > SLIP_MTU then
      -- your packet may have a problem, it is too large
   end if

   for packet_size loop               -- for each byte in packet
      serial_data = slip_rx_buffer -- do something with the packet data
   end loop
end procedure

-- your main loop
forever loop
   slip_poll() -- poll to receive slip data
   -- do other stuff but don't take too long
end loop

Generated by JALlib CHM Help System | Source: slip.jal


slip_init - JALlib Procedures Help

slip_init JALLIB PROCEDURE

Signature

procedure slip_init() is

Description

initalize slip

Include

To use this procedure, include the library:

include slip

Parameters

None

Return Value

None

Example

From sample file: 18f4525_slip_poll.jal

-- Title: Sample for SLIP (Serial Line IP)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample sends and receives SLIP (Serial Line IP) packets
--              for communication with serial data in packet form. This sample
--              will receive packets via poll method. You must continuously
--              poll the slip_poll() procedure.
--
-- Sources:
-- http://tools.ietf.org/html/rfc1055
--
-- Notes:
-- 1. The program will send hex 01 02 03 C0 05 06 DB 08 09 0A through SLIP which
--    will be encoded into slip format then sent via the serial port.
--    If you have your PC serial port connected, you will get this hex data:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0
-- 2. Now send back an encoded message:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0 (same as above).
--    SLIP will decode the data and echo back your original message:
--    01 02 03 C0 05 06 DB 08 09 0A
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SLIP
const word SLIP_MTU = 10  -- Max bytes per packet (Max Transfer Unit)
--
-- choose your interrupt routine. you may ignore this and create your own
-- isr or use polling method slip_poll()
const bit SLIP_USE_SERIAL_HW_ISR = FALSE -- TRUE = receive data via serial hw interrupt
--
-- choose your data carrier
alias slip_serial_data is serial_data
alias slip_data_available is serial_data_available
--
-- Choose the size of your receive buffer.
-- Should be the same as SLIP MTU if slip interrupts are not enabled
const byte QUEUE01_SIZE = SLIP_MTU
include queue01 -- include the queue/buffer library
alias slip_rx_buffer is queue01_nb  -- alias buffer for received data
--
-- Choose buffer to hold packet sizes
const byte QUEUE02_SIZE = 10
include queue02 -- include the queue/buffer library
alias slip_packet_size_buffer is queue02_nb     -- alias buffer for packet sizes
alias slip_packets_available is queue02_nr_used -- alias for number of packets avail
--
-- callback for when a full slip packet is received (not required for isr)
procedure slip_received_packet_callback() -- prototype
--
include slip -- include the library
--
slip_init() -- init the slip library

-- main program --

-- send some junk to ensure serial port is working
for 4 loop
   serial_data = 0
end loop

-- Send some data to the serial port in slip packet form
const byte test_data[SLIP_MTU] = {0x01,0x02,0x03,0xC0,0x05,0x06,0xDB,0x08,0x09,0x0A}
var byte count1 = 0
for SLIP_MTU loop                    -- loop through all bytes in packet
   slip_send_data(test_data[count1]) -- send slip packet data via serial port
   count1 = count1 + 1
end loop
-- if you don't send SLIP_MTU bytes, then you
-- must call slip_end_packet()
;slip_end_packet()

-- callback for when a full slip packet is received
procedure slip_received_packet_callback() is
   -- get the packet size
   var byte packet_size = slip_packet_size_buffer
   if packet_size > SLIP_MTU then
      -- your packet may have a problem, it is too large
   end if

   for packet_size loop               -- for each byte in packet
      serial_data = slip_rx_buffer -- do something with the packet data
   end loop
end procedure

-- your main loop
forever loop
   slip_poll() -- poll to receive slip data
   -- do other stuff but don't take too long
end loop

Generated by JALlib CHM Help System | Source: slip.jal


slip_poll - JALlib Procedures Help

slip_poll JALLIB PROCEDURE

Signature

procedure slip_poll() is

Description

poll procedure for receiving data

Include

To use this procedure, include the library:

include slip

Parameters

None

Return Value

None

Example

From sample file: 18f4525_slip_poll.jal

-- Title: Sample for SLIP (Serial Line IP)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample sends and receives SLIP (Serial Line IP) packets
--              for communication with serial data in packet form. This sample
--              will receive packets via poll method. You must continuously
--              poll the slip_poll() procedure.
--
-- Sources:
-- http://tools.ietf.org/html/rfc1055
--
-- Notes:
-- 1. The program will send hex 01 02 03 C0 05 06 DB 08 09 0A through SLIP which
--    will be encoded into slip format then sent via the serial port.
--    If you have your PC serial port connected, you will get this hex data:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0
-- 2. Now send back an encoded message:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0 (same as above).
--    SLIP will decode the data and echo back your original message:
--    01 02 03 C0 05 06 DB 08 09 0A
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SLIP
const word SLIP_MTU = 10  -- Max bytes per packet (Max Transfer Unit)
--
-- choose your interrupt routine. you may ignore this and create your own
-- isr or use polling method slip_poll()
const bit SLIP_USE_SERIAL_HW_ISR = FALSE -- TRUE = receive data via serial hw interrupt
--
-- choose your data carrier
alias slip_serial_data is serial_data
alias slip_data_available is serial_data_available
--
-- Choose the size of your receive buffer.
-- Should be the same as SLIP MTU if slip interrupts are not enabled
const byte QUEUE01_SIZE = SLIP_MTU
include queue01 -- include the queue/buffer library
alias slip_rx_buffer is queue01_nb  -- alias buffer for received data
--
-- Choose buffer to hold packet sizes
const byte QUEUE02_SIZE = 10
include queue02 -- include the queue/buffer library
alias slip_packet_size_buffer is queue02_nb     -- alias buffer for packet sizes
alias slip_packets_available is queue02_nr_used -- alias for number of packets avail
--
-- callback for when a full slip packet is received (not required for isr)
procedure slip_received_packet_callback() -- prototype
--
include slip -- include the library
--
slip_init() -- init the slip library

-- main program --

-- send some junk to ensure serial port is working
for 4 loop
   serial_data = 0
end loop

-- Send some data to the serial port in slip packet form
const byte test_data[SLIP_MTU] = {0x01,0x02,0x03,0xC0,0x05,0x06,0xDB,0x08,0x09,0x0A}
var byte count1 = 0
for SLIP_MTU loop                    -- loop through all bytes in packet
   slip_send_data(test_data[count1]) -- send slip packet data via serial port
   count1 = count1 + 1
end loop
-- if you don't send SLIP_MTU bytes, then you
-- must call slip_end_packet()
;slip_end_packet()

-- callback for when a full slip packet is received
procedure slip_received_packet_callback() is
   -- get the packet size
   var byte packet_size = slip_packet_size_buffer
   if packet_size > SLIP_MTU then
      -- your packet may have a problem, it is too large
   end if

   for packet_size loop               -- for each byte in packet
      serial_data = slip_rx_buffer -- do something with the packet data
   end loop
end procedure

-- your main loop
forever loop
   slip_poll() -- poll to receive slip data
   -- do other stuff but don't take too long
end loop

Generated by JALlib CHM Help System | Source: slip.jal


slip_send_data - JALlib Procedures Help

slip_send_data JALLIB PROCEDURE

Signature

procedure slip_send_data(byte in data) is

Description

Sends one byte of packet data

Include

To use this procedure, include the library:

include slip

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f4525_slip_poll.jal

-- Title: Sample for SLIP (Serial Line IP)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample sends and receives SLIP (Serial Line IP) packets
--              for communication with serial data in packet form. This sample
--              will receive packets via poll method. You must continuously
--              poll the slip_poll() procedure.
--
-- Sources:
-- http://tools.ietf.org/html/rfc1055
--
-- Notes:
-- 1. The program will send hex 01 02 03 C0 05 06 DB 08 09 0A through SLIP which
--    will be encoded into slip format then sent via the serial port.
--    If you have your PC serial port connected, you will get this hex data:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0
-- 2. Now send back an encoded message:
--    C0 01 02 03 DB DC 05 06 DB DD 08 09 0A C0 (same as above).
--    SLIP will decode the data and echo back your original message:
--    01 02 03 C0 05 06 DB 08 09 0A
--
-- This file has been generated by Matt's sample generator.
--

-- include chip
include 18f4525                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT -- internal oscillator
pragma target clock 32_000_000    -- oscillator frequency
pragma target wdt  CONTROL
pragma target lvp  ENABLED
pragma target MCLR EXTERNAL        -- reset externally
pragma target XINST DISABLED       -- not supported by JalV2
--
OSCCON_IRCF = 0b111  -- set internal osc to 8mhz
OSCTUNE_PLLEN = true -- enable PPL, multiply internal osc by 4
--
enable_digital_io()  -- make all pins digital I/O
_usec_delay(100_000) -- wait for power to settle

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SLIP
const word SLIP_MTU = 10  -- Max bytes per packet (Max Transfer Unit)
--
-- choose your interrupt routine. you may ignore this and create your own
-- isr or use polling method slip_poll()
const bit SLIP_USE_SERIAL_HW_ISR = FALSE -- TRUE = receive data via serial hw interrupt
--
-- choose your data carrier
alias slip_serial_data is serial_data
alias slip_data_available is serial_data_available
--
-- Choose the size of your receive buffer.
-- Should be the same as SLIP MTU if slip interrupts are not enabled
const byte QUEUE01_SIZE = SLIP_MTU
include queue01 -- include the queue/buffer library
alias slip_rx_buffer is queue01_nb  -- alias buffer for received data
--
-- Choose buffer to hold packet sizes
const byte QUEUE02_SIZE = 10
include queue02 -- include the queue/buffer library
alias slip_packet_size_buffer is queue02_nb     -- alias buffer for packet sizes
alias slip_packets_available is queue02_nr_used -- alias for number of packets avail
--
-- callback for when a full slip packet is received (not required for isr)
procedure slip_received_packet_callback() -- prototype
--
include slip -- include the library
--
slip_init() -- init the slip library

-- main program --

-- send some junk to ensure serial port is working
for 4 loop
   serial_data = 0
end loop

-- Send some data to the serial port in slip packet form
const byte test_data[SLIP_MTU] = {0x01,0x02,0x03,0xC0,0x05,0x06,0xDB,0x08,0x09,0x0A}
var byte count1 = 0
for SLIP_MTU loop                    -- loop through all bytes in packet
   slip_send_data(test_data[count1]) -- send slip packet data via serial port
   count1 = count1 + 1
end loop
-- if you don't send SLIP_MTU bytes, then you
-- must call slip_end_packet()
;slip_end_packet()

-- callback for when a full slip packet is received
procedure slip_received_packet_callback() is
   -- get the packet size
   var byte packet_size = slip_packet_size_buffer
   if packet_size > SLIP_MTU then
      -- your packet may have a problem, it is too large
   end if

   for packet_size loop               -- for each byte in packet
      serial_data = slip_rx_buffer -- do something with the packet data
   end loop
end procedure

-- your main loop
forever loop
   slip_poll() -- poll to receive slip data
   -- do other stuff but don't take too long
end loop

Generated by JALlib CHM Help System | Source: slip.jal


smbus_mlx90615.jal - JALLIB Library Documentation

smbus_mlx90615.jal JALLIB LIBRARY

Title

SM bus library for Melexis IR sensor MLX90615

Author

Vasile Surducan, Copyright (c) 2010...2012, all rights reserved., Adapted-by:

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

software implementation for single SMbus master, use 4 hw stack
define SM_bus pins like:
alias SM_SCL is pin_C3
alias SM_SCL_direction is pin_C3_direction

alias SM_SDA is pin_C4
alias SM_SDA_direction is pin_C4_direction
ATTENTION: both SM_SDA and SM_SCL must have pull-up resistors
Procedures which can be used by the application program:

procedure SM_START_bit
procedure SM_STOP_bit
function SM_transmit_byte( byte in TX_buffer )return bit
function SM_receive_byte( bit in ack_noack ) return byte
procedure read_MEM ( byte in senzor_address, byte in MEM_address )
procedure write_MEM ( byte in senzor_address, byte in MEM_address,
byte in MEM_high, byte in MEM_low, byte in PEC )is
procedure MLX90615_sleep ( byte in senzor_address )
procedure MLX90615_wake
procedure calculate_temp_C
procedure calculate_temp_K
todo: procedure calculate_CRC8 and/or procedure SM_receive_byte_with_CRC8

Constants and Variables

config - var word
ACK - const bit = low
NACK - const bit = high
mlx90615_ack - var bit = high
mem_low - var byte = 0
mem_high - var byte = 0
t_high - var byte = 0
s_t_high - var sword = 0
w_t_high - var word = 0
pec - var byte = 0
temperature - var sword = 0
temp - var word = 0
temperature_c - var sword = 0
temperature_k - var word = 0
nack_counter - var byte = 0

Routines

  • _scl_high - Procedure
  • _scl_low - Procedure
  • _sda_high - Procedure
  • _sda_low - Procedure
  • _sm_receive_bit - Procedure
  • _sm_send_bit - Procedure
  • calculate_temp_c - Procedure
  • calculate_temp_k - Procedure
  • mlx90615_sleep - Procedure
  • mlx90615_wake - Procedure
  • sm_bus_initialize - Procedure
  • sm_receive_byte - Function returns byte
  • sm_start_bit - Procedure
  • sm_stop_bit - Procedure
  • sm_transmit_byte - Function returns bit


spi2_init - JALlib Procedures Help

spi2_init JALLIB PROCEDURE

Signature

procedure spi2_init(byte in spi_mode, byte in spi_rate) is

Description

Initialize the SPI registers.
Note: check your datasheet -- TRIS settings, any SPI errata?

Include

To use this procedure, include the library:

include spi_host_hw2

Parameters

  • spi_mode - byte in
  • spi_rate - byte in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: spi_host_hw2.jal


spi_common.jal - JALLIB Library Documentation

spi_common.jal JALLIB LIBRARY

Title

SPI Master common definition

Author

Sebastien Lelong(c) 2011, all rights reserved.

Compiler

2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

SPI Master common constant definition, used both by MSSP1 and MSSP2

Notes

content was extracted from spi_master_hw.jal at rev 1537
http://code.google.com/p/jallib/source/browse/trunk/include/peripheral/spi/spi_master_hw.jal?r=1537

Use these when calling the spi_init() routine below ( SPI master mode )


spi_host_hw2.jal - JALLIB Library Documentation

spi_host_hw2.jal JALLIB LIBRARY

Title

SPI host, driving MSSP2 module

Author

Sebastien Lelong Copyright (c) 2011, all rights reserved.

Compiler

2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

SPI host hardware control.
Routines for sending and receiving through the SPI in host mode, using MSSP2

Notes

this is a rough duplication of spi_host_hw.jal at rev 1537,
(http://code.google.com/p/jallib/source/browse/trunk/include/peripheral/spi/spi_host_hw.jal?r=1537)
originally written by William Welch, from which MSSP1 registers were modified to match MSSP2 names.

Sources

good overview of SPI at http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
also at: http://elm-chan.org/docs/spi_e.html

Routines

  • spi2_init - Procedure
  • spi_host_hw2'get - Function returns byte
  • spi_host_hw2'put - Procedure
  • spi_host_hw2_exchange - Function returns byte
  • spi_host_hw2_set_mode - Procedure
  • spi_host_hw2_set_mode_00 - Procedure
  • spi_host_hw2_set_mode_01 - Procedure
  • spi_host_hw2_set_mode_10 - Procedure
  • spi_host_hw2_set_mode_11 - Procedure
  • spi_host_hw2_set_speed - Procedure


spi_host_hw.jal - JALLIB Library Documentation

spi_host_hw.jal JALLIB LIBRARY

Title

SPI host

Author

William Welch Copyright (c) 2009, all rights reserved., Adapted-by: Sebastien Lelong

Compiler

2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

SPI host hardware control.
Routines for sending and receiving through the SPI in host mode

Sources

good overview of SPI at http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
also at: http://elm-chan.org/docs/spi_e.html

Routines

  • spi_host_hw'get - Function returns byte
  • spi_host_hw'put - Procedure
  • spi_host_hw_exchange - Function returns byte
  • spi_host_hw_set_mode - Procedure
  • spi_host_hw_set_mode_00 - Procedure
  • spi_host_hw_set_mode_01 - Procedure
  • spi_host_hw_set_mode_10 - Procedure
  • spi_host_hw_set_mode_11 - Procedure
  • spi_host_hw_set_speed - Procedure
  • spi_init - Procedure


spi_init - JALlib Procedures Help

spi_init JALLIB PROCEDURE

Signature

procedure spi_init(byte in spi_mode, byte in spi_rate) is

Description

Initialize the SPI registers.
Note: check your datasheet -- TRIS settings, any SPI errata?

Include

To use this procedure, include the library:

include spi_host_hw

Parameters

  • spi_mode - byte in
  • spi_rate - byte in

Return Value

None

Example

From sample file: 18f4620_sd_card.jal

-- Title: Library for communicating with SD memory cards
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this library provides functions for SD memory cards.
--
-- Sources:
-- SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
-- How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup the sd card pins
alias sd_chip_select is pin_SS
alias sd_chip_select_direction is pin_SS_direction
sd_chip_select = high
sd_chip_select_direction = output
--
-- setup the sd card library
alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1
;const bit SD_READ_EXTRA_SPEED = TRUE -- extra read speed
;const bit SD_WRITE_EXTRA_SPEED = TRUE -- extra write speed
;const bit SD_DELAY_AFTER_WRITE = FALSE ;Try this if you are having troulbe with your card.
include sd_card              -- include the sd card ide hard disk library
sd_init()                    -- initialize startup settings

if sd_has_error == TRUE then
   print_string(serial_data, "ERROR - SD CARD FAILED\r\n")
else
   if sd_card_type == SD_STANDARD_CAPACITY then
      print_string(serial_data, "Standard capacity ")
   elsif sd_card_type == SD_HIGH_CAPACITY then
      print_string(serial_data, "High capacity ")
   end if
   print_string(serial_data, "SD card successfully loaded!\r\n")
end if

------------------------------------------------------------
-- START of PROGRAM
------------------------------------------------------------
_usec_delay(100_000)                  -- wait for power to settle

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- Send something to the serial port
seperator()             -- send "----" via serial port
print_string(serial_data,"SD CARD SAMPLE STARTED")
print_crlf(serial_data)

-- variables for the sample
var word step1
var byte volatile data

seperator()            -- seperate the examples with "----"

print_string(serial_data,"SD Card Size (bytes): ")
print_dword_dec(serial_data,sd_number_of_sectors*SD_BYTE_PER_SECTOR)

seperator()            -- seperate the examples with "----"
--------------------------------------------------------------------------------
-- EXAMPLE #1 read sector 0 (the boot sector) & sector 1, one byte at a time
--------------------------------------------------------------------------------
sd_start_read(0)           -- get sd card ready for read at sector 0
for 512 * 2 loop           -- read 2 sectors (512 * 2 bytes)
  data = sd_data_byte      -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
--------------------------------------------------------------------------------
-- EXAMPLE #2 write to a sector 1 byte at a time
--------------------------------------------------------------------------------
sd_start_write(20)         -- get sd card ready for write at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
  sd_data_byte = "A"       -- write 1 bytes of data
end loop
sd_stop_write()            -- tell sd card you are done reading
--
-- read the data back
sd_start_read(20)          -- get sd card ready for read at sector 20
for 512 + 256 loop         -- loop 1 sector + 1 half sector (512 + 256 bytes)
 data = sd_data_byte       -- read 1 bytes of data
  serial_write(data)    -- send byte via serial port
end loop
sd_stop_read()             -- tell sd card you are done reading

seperator()                -- seperate the examples with "----"
_usec_delay(500_000)       -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #3 write to 2 sectors using a sector buffer at a address
;   -- user friendly and fastest.
;   --------------------------------------------------------------------------------
;   -- fill the sector buffer with data
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "B"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 20
;   sd_write_sector_address(20)
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      sd_sector_buffer[step1] = "C"             -- set each byte of data
;   end loop
;   -- write the sector buffer to sector 21
;   sd_write_sector_address(21)
;   --
;   -- read back the same sectors
;   -- read sector 20 into the sector buffer
;   sd_read_sector_address(20)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read sector 21 into the sector buffer
;   sd_read_sector_address(21)
;   -- now send it to the serial port
;   for 512 using step1 loop                     -- loop till the end of the sector buffer
;      serial_write (sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;
;   seperator()                                  -- seperate the examples with "----"
;   _usec_delay(500_000)                         -- a small delay
;   --------------------------------------------------------------------------------
;   -- EXAMPLE #4 write to 2 sectors using a sector buffer. About the same speed as
;   -- example 3.
;   --------------------------------------------------------------------------------
;   -- get sd card ready for write at sector 20
;   sd_start_write(20)
;   -- fill the sector buffer with data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "D"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()
;   -- fill the sector buffer with new data
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     sd_sector_buffer[step1] = "E"            -- set each byte of data
;   end loop
;   -- write the sector buffer to the sd card
;   sd_write_sector()                          -- write the buffer to the sd card
;   -- tell sd card you are done writing
;   sd_stop_write()
;   --
;   -- read back both of the same sectors
;   -- get sd card ready for read at sector 20
;   sd_start_read(20)
;   -- read the sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   -- read the next sector into the sector buffer
;   sd_read_sector()
;   -- now send it to the serial port
;   for 512 using step1 loop                   -- loop till the end of the sector buffer
;     serial_write(sd_sector_buffer[step1]) -- send each byte via serial port
;   end loop
;   sd_stop_read()                             -- tell sd card you are done reading

-------THE END!--------

Generated by JALlib CHM Help System | Source: spi_host_hw.jal


spi_master_hw2.jal - JALLIB Library Documentation

spi_master_hw2.jal JALLIB LIBRARY

Title

SPI Master, driving MSSP2 module

Author

Sebastien Lelong Copyright (c) 2011, all rights reserved.

Compiler

2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library has been moved to spi_host_hw2 due to terminology concerns.

Notes

this is a rough duplication of spi_master_hw.jal at rev 1537,
(http://code.google.com/p/jallib/source/browse/trunk/include/peripheral/spi/spi_master_hw.jal?r=1537)
originally written by William Welch, from which MSSP1 registers were modified to match MSSP2 names.

Sources

good overview of SPI at http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
also at: http://elm-chan.org/docs/spi_e.html


spi_master_hw.jal - JALLIB Library Documentation

spi_master_hw.jal JALLIB LIBRARY

Title

SPI Master

Author

William Welch Copyright (c) 2009, all rights reserved., Adapted-by: Sebastien Lelong

Compiler

2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library has been moved to spi_host_hw due to terminology concerns.

Sources

good overview of SPI at http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
also at: http://elm-chan.org/docs/spi_e.html


spi_master_sw.jal - JALLIB Library Documentation

spi_master_sw.jal JALLIB LIBRARY

Title

SPI Master Software

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

SPI Master software control.
Routines for sending and receiving through SPI software in master mode

Notes

alias spi_master_sw_sdi is pin_sdi
alias spi_master_sw_sdi_direction is pin_sdi_direction
alias spi_master_sw_sdo is pin_sdo
alias spi_master_sw_sdo_direction is pin_sdo_direction
alias spi_master_sw_sck is pin_sck
alias spi_master_sw_sck_direction is pin_sck_direction
-- define spi inputs/outputs
spi_master_sw_sdi_direction = input -- spi input
spi_master_sw_sdo_direction = output -- spi output
spi_master_sw_sck_direction = output -- spi clock
--
include spi_master_sw
spi_init(SPI_MODE_11) -- init spi, choose mode

Sources

Jallib spi_master_hw library - Written by William Welch
http://www.justanotherlanguage.org/content/jallib/tutorials/tutorial_spi_introduction
http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf

Routines

  • spi_master_sw'get - Function returns byte
  • spi_master_sw'put - Procedure
  • spi_master_sw_exchange - Function returns byte
  • spi_master_sw_init - Procedure
  • spi_master_sw_set_mode - Procedure
  • spi_master_sw_set_mode_00 - Procedure
  • spi_master_sw_set_mode_01 - Procedure
  • spi_master_sw_set_mode_10 - Procedure
  • spi_master_sw_set_mode_11 - Procedure
  • spi_master_sw_set_speed - Procedure


spi_master_sw_init - JALlib Procedures Help

spi_master_sw_init JALLIB PROCEDURE

Signature

procedure spi_master_sw_init(byte in spi_mode) is

Description

init spi

Include

To use this procedure, include the library:

include spi_master_sw

Parameters

  • spi_mode - byte in

Return Value

None

Example

From sample file: 18f27j53_mcp4922.jal

--------------------------------------------------------------------------------
-- Title: MCP4922_example.jal
-- Author: Peter Lankreijer
-- Adapted-by: Sebastien Lelong, Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This program is to show the usage of the MCP4922 library.
--
-- This file has been generated by hand (manually maintained)
--

include 18f27j53

pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
pragma target IOL1WAY disabled   -- Mapping allowed multiple time at runtime
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

include delay

-- setup SPI
alias spi_master_sw_sdi                  is pin_B2
alias spi_master_sw_sdi_direction        is pin_B2_direction
alias spi_master_sw_sdo                  is pin_A2
alias spi_master_sw_sdo_direction        is pin_A2_direction
alias spi_master_sw_sck                  is pin_A3
alias spi_master_sw_sck_direction        is pin_A3_direction

include spi_master_sw

spi_master_sw_sdi_direction = input      -- spi input
spi_master_sw_sdo_direction = output     -- spi output
spi_master_sw_sck_direction = output     -- spi clock

spi_master_sw_init(SPI_MODE_11)
alias spi_master is spi_master_sw
alias spi_master_exchange is spi_master_sw_exchange

-- setup of the DAC
alias mcp4922_cs                         is pin_A1
alias mcp4922_cs_direction               is pin_A1_direction
alias mcp4922_ldac                       is pin_A7
alias mcp4922_ldac_direction             is pin_A7_direction

var bit buffer = 1                       -- buffered
var bit gain = 0                         -- 2 * Vref * D/4096

include dac_mcp4922

mcp4922_init(buffer, gain)

-- main program

var word dac_value_a = 0              -- value between 0 and 4096
var word dac_value_b = 4000

forever loop
   for 20 loop
       dac_value_a = dac_value_a + 200
       dac_value_b = dac_value_b - 200

       mcp4922_dac_ab(dac_value_a, dac_value_b)

       delay_100ms(5)
   end loop

   for 20 loop
       dac_value_a = dac_value_a - 200
       dac_value_b = dac_value_b + 200

       mcp4922_dac_a(dac_value_a)
       mcp4922_dac_a(dac_value_b)

       delay_100ms(5)
   end loop

end loop

Generated by JALlib CHM Help System | Source: spi_master_sw.jal


spi_slave_hw.jal - JALLIB Library Documentation

spi_slave_hw.jal JALLIB LIBRARY

Title

SPI Slav0e Hardware

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

SPI Hardware Slave library for exchanging data through SPI bus.

Notes

Watch your master speed! SPI master will not slow down for slow slave.
Use a high osc speed on slave or maybe tx a byte back to the master
when slave is ready for more.
When SPI_SLAVE_HW_ENABLE_INTERRUPT are disabled, calling of any spi procedure
will pause your main program until the master does a spi exchange.
When SPI_SLAVE_HW_ENABLE_INTERRUPT are enabled, all input/output bytes will be
placed into a buffer. Data will get transferred whenever the master does a
spi exchange. Your main program will be paused while data is arriving
untill chip select goes active again. You will know when data is in the
buffer by reading the variable spi_slave_hw_rx_queue_is_empty or
spi_slave_hw_rx_queue_nr_used. You should also monitor
spi_slave_hw_tx_queue_is_full and not send data if it is set to TRUE.
When SYNCHRONOUS_SLAVE_MODE is disabled, you can choose any chip select pin.
You must control & listen to your chip select pin in software. You can do
sync by calling spi_slave_hw_sync(). I do suggest you use pin_ss.
When SYNCHRONOUS_SLAVE_MODE is enabled, The pin_ss (slave select / chip
select pin) must be used. PIC will listen on this pin (active low). This
will also reset the PIC's SPI module each time ss pin is disabled.
This ensures correct synchronization of input bytes.
You could use a interrupt on change pin to detect the start and end
of a packet. I have not tried this yet.
Here is an example setup for this library:
-- Setup SPI Slave Hardware
--
pin_sdi_direction = input -- spi input
pin_sdo_direction = output -- spi output
pin_sck_direction = input -- spi clock
--
alias spi_slave_hw_chip_select is pin_ss -- slave select / chip select pin.
alias spi_slave_hw_chip_select_direction is pin_ss_direction
spi_slave_hw_chip_select_direction = input
const SPI_SLAVE_HW_SS_ACTIVE_STATE = LOW -- chip select pin is active low
--
-- chip select must be pin_ss & active low if TRUE. See more notes in library.
const SPI_SLAVE_HW_SYNCHRONOUS = TRUE
--
const SPI_SLAVE_HW_ENABLE_INTERRUPT = TRUE -- enable spi interrupt
--
if SPI_SLAVE_HW_ENABLE_INTERRUPT == TRUE then
const SPI_SLAVE_HW_TX_QUEUE_SIZE = 50 -- tx queue
const SPI_SLAVE_HW_RX_QUEUE_SIZE = 50 -- rx queue
end if
--
-- Enable/Disable Packets. Currently only works with interrupts enabled.
-- (pin_ss = inactive) marks end of packet.
const SPI_SLAVE_ENABLE_ISR_PACKETS = TRUE
--
if SPI_SLAVE_ENABLE_ISR_PACKETS == TRUE then
const SPI_SLAVE_HW_RX_PACKET_SIZES = 5 -- packet size queue
end if
--
include spi_slave_hw
spi_slave_init(SPI_MODE_11)
--
spi_slave_hw = 255 -- the first byte to go out

Sources

http://www.justanotherlanguage.org/content/jallib/tutorials/tutorial_spi_introduction
Jallib spi_master_hw library - Written by William Welch
http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf

Constants and Variables

QUEUE01_SIZE - const byte = SPI_SLAVE_HW_RX_QUEUE_SIZE
QUEUE02_SIZE - const byte = SPI_SLAVE_HW_TX_QUEUE_SIZE
QUEUE03_SIZE - const byte = SPI_SLAVE_HW_RX_PACKET_SIZES
spi_slave_hw_rx_byte_count - var byte = 0
spi_slave_hw_rx_byte_count_old - var byte = 0

Routines

  • exchange1 - Procedure
  • exchange2 - Procedure
  • spi_slave_hw'get - Function returns byte
  • spi_slave_hw'put - Procedure
  • spi_slave_hw_exchange - Function returns byte
  • spi_slave_hw_packet_available'get - Function returns bit
  • spi_slave_hw_sync - Procedure
  • spi_slave_init - Procedure
  • spi_slave_initerrupt - Procedure


spi_slave_hw_exchange - JALlib Procedures Help

spi_slave_hw_exchange JALLIB FUNCTION

Signature

function spi_slave_hw_exchange(byte in data) return byte is

Description

wait to exchange data through the spi port
(wait for chip select to go low, and clock pulses to come in from master)

Include

To use this procedure, include the library:

include spi_slave_hw

Parameters

  • data - byte in

Return Value

byte - Function return value

Example

From sample file: 18f4620_spi_slave_hw.jal

-- Title: SPI Slave Hardware Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Compiler: 2.4o
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: SPI Hardware Slave library for exchanging data through SPI bus.
--              To use this sample have your master SPI exchange 10 bytes
--              every 1 second with SPI_MODE_11,SPI_RATE_FOSC_64.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.justanotherlanguage.org/content/jallib/tutorials/tutorial_spi_introduction
-- Jallib spi_master_hw library - Written by William Welch
-- http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf
--

-- include chip
include 18f4620                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110  -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

-- Specify the pin to which the LED (with serial resistor!) is connected:
alias   led      is pin_A0
pin_A0_direction =  output

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print
include format

-- Setup SPI Slave Hardware
--
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = input    -- spi clock
--
alias spi_slave_hw_chip_select is pin_ss -- slave select / chip select pin.
alias spi_slave_hw_chip_select_direction is pin_ss_direction
spi_slave_hw_chip_select_direction = input
const SPI_SLAVE_HW_SS_ACTIVE_STATE = LOW -- chip select pin is active low
--
-- chip select must be pin_ss & active low if TRUE. See more notes in library.
const SPI_SLAVE_HW_SYNCHRONOUS = TRUE
--
const SPI_SLAVE_HW_ENABLE_INTERRUPT = TRUE -- enable spi interrupt
--
if SPI_SLAVE_HW_ENABLE_INTERRUPT == TRUE then
   const SPI_SLAVE_HW_TX_QUEUE_SIZE = 25 -- tx queue
   const SPI_SLAVE_HW_RX_QUEUE_SIZE = 25 -- rx queue
end if
--
-- Enable/Disable Packets. Currently only works with interrupts enabled.
-- (pin_ss = inactive) marks end of packet.
const SPI_SLAVE_ENABLE_ISR_PACKETS = TRUE
--
if SPI_SLAVE_ENABLE_ISR_PACKETS == TRUE then
   const SPI_SLAVE_HW_RX_PACKET_SIZES = 10 -- packet size queue
end if
--
include spi_slave_hw
spi_slave_init(SPI_MODE_11)
--
spi_slave_hw = 255 -- the first byte to go out

-- MAIN PROGRAM

var byte x,y
var byte step
for 10 using step loop
   spi_slave_hw = step
end loop

led = ON

forever loop

   -- EXAMPLE #1 - if ISR packets are enabled
   if (SPI_SLAVE_HW_ENABLE_INTERRUPT == TRUE) & (SPI_SLAVE_ENABLE_ISR_PACKETS == TRUE) then
      if spi_slave_hw_packet_available then

         -- get the packet size (only read this var once)
         var byte size = spi_slave_hw_rx_packet_size

         print_crlf(serial_data)
         const byte message[] = "Bytes in packet: "
         print_string(serial_data, message)
         print_byte_dec(serial_data,size)
         print_crlf(serial_data)

         for size loop

            ;spi_slave_hw = 50 -- set a SPI return value
            ;x = spi_slave_hw   -- read one byte
            x = spi_slave_hw_exchange(50)

            format_byte_dec(serial_data,x,3,0)
            serial_data = " "

         end loop

         print_crlf(serial_data)
         print_crlf(serial_data)
      end if

      -- do other things here
      _usec_delay(1000)
   end if

   -- EXAMPLE #2 - if ISR packets are disabled
   if (SPI_SLAVE_HW_ENABLE_INTERRUPT == TRUE) & (SPI_SLAVE_ENABLE_ISR_PACKETS == FALSE) then
      var byte y = 0
      while spi_slave_hw_rx_queue_nr_used > 0 loop

         ;spi_slave_hw = 50 -- set a SPI return value
         ;x = spi_slave_hw   -- read one byte
         x = spi_slave_hw_exchange(50)

         print_byte_dec(serial_data,x)
         serial_data = " "
         y = 1
      end loop

      if y == 1 then
         print_crlf(serial_data)
      end if
      -- do other things here
      _usec_delay(1000)
   end if

   -- EXAMPLE #3 - no interrupts
   -- this example assumes we are waiting for 10 bytes at a time
   var byte input_array[10] -- assuming packets are always 13 bytes
   if (SPI_SLAVE_HW_ENABLE_INTERRUPT == FALSE) then

      if spi_slave_hw_chip_select == SPI_SLAVE_HW_SS_ACTIVE_STATE then

         x = 0
         for count(input_array) loop
            input_array[x] = spi_slave_hw_exchange(50)
            x = x + 1
         end loop

         -- do other things here, you may loose data if more comes in.
         for count(input_array) using x loop
            print_byte_dec(serial_data,input_array[x])
            serial_data = " "
         end loop
      end if
   end if

end loop

Generated by JALlib CHM Help System | Source: spi_slave_hw.jal


spi_slave_init - JALlib Procedures Help

spi_slave_init JALLIB PROCEDURE

Signature

procedure spi_slave_init(byte in spi_mode) is

Description

spi slave init

Include

To use this procedure, include the library:

include spi_slave_hw

Parameters

  • spi_mode - byte in

Return Value

None

Example

From sample file: 18f4620_spi_to_serial.jal

-- Title: SPI Slave Hardware Sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Compiler: 2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Recieves data via SPI, outputs to serial port.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.justanotherlanguage.org/content/jallib/tutorials/tutorial_spi_introduction
-- Jallib spi_master_hw library - Written by William Welch
-- http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf
--
-- Notes:
-- The master should send slower then the slave can recieve, else data
-- will be lost. Try using SPI_RATE_FOSC_16 or SPI_RATE_FOSC_64 at master.
--
--    spi_init(SPI_MODE_11,SPI_RATE_FOSC_16)
--

-- include chip
include 18f4620                   -- target picmicro
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110  -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
enable_digital_io()                -- make all pins digital I/O
--
_usec_delay(100_000) -- wait for power to settle

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print
print_string(serial_data,"SAMPLE STARTED")
print_crlf(serial_data)

include format

-- Setup SPI Slave Hardware
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = input    -- spi clock
--
alias spi_slave_hw_chip_select is pin_ss    -- slave select / chip select pin.
alias spi_slave_hw_chip_select_direction is pin_ss_direction
spi_slave_hw_chip_select_direction = input
const SPI_SLAVE_HW_SS_ACTIVE_STATE = LOW -- chip select pin is active low
--
-- chip select must be pin_ss & active low if TRUE. See more notes in library.
const SPI_SLAVE_HW_SYNCHRONOUS = TRUE
--
const SPI_SLAVE_HW_ENABLE_INTERRUPT = TRUE -- recieve data via interrupt
--
if SPI_SLAVE_HW_ENABLE_INTERRUPT == TRUE then
   const SPI_SLAVE_HW_TX_QUEUE_SIZE = 254 -- tx queue
   const SPI_SLAVE_HW_RX_QUEUE_SIZE = 254 -- rx queue
end if
--
-- Enable/Disable Packets. Currently only works with interrupts enabled.
-- (SPI_SLAVE_HW_SS_ACTIVE_STATE = low) marks end of packet.
const SPI_SLAVE_ENABLE_ISR_PACKETS = FALSE
--
include spi_slave_hw
spi_slave_init(SPI_MODE_11)
--

-- MAIN PROGRAM
forever loop
   while spi_slave_hw_rx_queue_nr_used > 0 loop
      serial_data = spi_slave_hw
   end loop
end loop

Generated by JALlib CHM Help System | Source: spi_slave_hw.jal


sqrt16 - JALlib Procedures Help

sqrt16 JALLIB FUNCTION

Signature

function sqrt16(word in x) return byte is

Description

Title: Calculate the square root of an unsigned 16-bits integer
Arguments: unsigned 16-bits integer
Returns: unsigned 8-bits integer
Original: author: Kyle York

Include

To use this procedure, include the library:

include math

Parameters

  • x - word in

Return Value

byte - unsigned 8-bits integer Original: author: Kyle York

Example

From sample file: 16f886_math.jal

-- ------------------------------------------------------
-- Title: Sample of use of mathematical routines
--
-- Author: Rob Hamerling, Copyright (c) 2009, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4l
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Sample mathematical (tes) program for Microchip PIC16f886.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f886                     -- target PICmicro
--
-- This program assumes a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
-- configuration memory settings (fuses)
pragma target OSC  HS               -- HS crystal or resonator
pragma target WDT  control          -- watchdog
pragma target LVP  enabled          -- allow Low Voltage Programming
pragma target MCLR external         -- reset externally
--
wdtcon_swdten = 0b_0                -- disable watchdog
--
enable_digital_io()                 -- disable analog I/O (if any)
--
include print
include delay
--
const serial_hw_serial   = true      -- RS232
const serial_hw_baudrate = 19200     -- speed
include serial_hardware             -- serial library
serial_hw_init()
--
include math                        -- ibrary with math functions
--
alias   led      is pin_C1          -- LED to show looping
pin_C1_direction =  output
--
var word r16                        -- destination of 32 bits result
var byte r8                         -- destination of 16 bits result
--
forever loop

  LED = !LED                        -- flip

  r16 = sqrt32(256*256 + 513)
  print_word_dec(serial_hw_data,r16)
  print_crlf(serial_hw_data)
  delay_100ms(3)

  r8  = sqrt16(16*16 + 33)
  print_byte_dec(serial_hw_data,r8)
  print_crlf(serial_hw_data)

  delay_100ms(3)

end loop
--

Generated by JALlib CHM Help System | Source: math.jal


sqrt32 - JALlib Procedures Help

sqrt32 JALLIB FUNCTION

Signature

function sqrt32(dword in x) return word is

Description

Title: Calculate the square root of an unsigned 32-bits integer
Arguments: unsigned 32-bits integer
Returns: unsigned 16-bits integer
Original: Kyle York

Include

To use this procedure, include the library:

include math

Parameters

  • x - dword in

Return Value

word - unsigned 16-bits integer Original: Kyle York

Example

From sample file: 18f4550_sqrt.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for sqrt.jal
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program
--
-- Sources:
--
-- Notes: as output, this sample produces characters on a serial link. First
--        run serial tests to make sure serial comms works okay.
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f4550_af.jal
--    * test : test_sqrt.jal
--

;@jallib section chipdef
-- chip setup
include 18f4550

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 - 20MHZ_INPUT
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog saler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target CCP2MUX       pin_C1      -- CCP2 on pin C1
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          EXTERNAL    -- master reset on RE3
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CP2           DISABLED    -- code block 2 not protected
pragma target CP3           DISABLED    -- code block 3 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target CPD           DISABLED    -- eeprom code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRT2          DISABLED    -- table write block 2 not protected
pragma target WRT3          DISABLED    -- table write block 3 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTD          DISABLED    -- eeprom not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTR2         DISABLED    -- table read block 2 not protected
pragma target EBTR3         DISABLED    -- table read block 3 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog
;@jallib section led
-- LED IO definition
alias led is pin_b3
alias led_direction is pin_b3_direction
alias led2 is pin_b1
alias led2_direction is pin_b1_direction

include delay
include print

-- set all IO as digital
enable_digital_io()

-- setup serial (see echo.jal for more details);@jallib section serial
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
include profiler

include math

led_direction = output

var word r

forever loop
   delay_100ms( 5 )
   LED = high
   delay_100ms( 5 )
   LED = low

   -- serial_hw_data is a pseudo-var of the desired output-device.
   serial_hw_data = "A" -- output an A to the serial port.

   profiler_setup(0)

   profiler_start()
   r = sqrt32(65535*65533)
   profiler_stop_and_report(serial_hw_data)

   print_word_dec(serial_hw_data, r)

end loop

Generated by JALlib CHM Help System | Source: math.jal


sr_commit - JALlib Procedures Help

sr_commit JALLIB PROCEDURE

Signature

procedure sr_commit() is

Description

sr_commit - commit (activate) previous provided data
Note: the RCK pin is set to low in the write() procedure,
as a preperation for the commit.

Include

To use this procedure, include the library:

include shift_register_74595

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_sr_74595.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for 74595 shift register
--
-- Author: Joep Suijs, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    test setup: 3 x 74595 cascaded
--    sr_sda connects to SER_IN / DS pin of 74595 #1
--    SER_OUT / Q7S of 74595 #1 connects to SER_IN / DS pin of 74595 #2
--    SER_OUT / Q7S of 74595 #2 connects to SER_IN / DS pin of 74595 #3
--    sr_scl is connected the SRCK / SHCP pin of all three 74595 chips
--    sr_rck is connected the RCK / STCP pin of all three 74595 chips
--    sr_g is connected the G / OE pin of all three 74595 chips
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_sr_74595.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

enable_digital_io() -- disable analog I/O (if any)

include delay
include seven_segment

-- define IO pin's
alias sr_rck   is pin_a0   ; RCK (parallel clock / load, rising edge)
alias sr_sda   is pin_a1   ; SER_IN   / DS
alias sr_scl   is pin_a2   ; SRCK  (serial clock, rising egde)
alias sr_g     is pin_a3   ; G (output enable, low = enable)

-- set IO pins to output
pin_a0_direction = output
pin_a1_direction = output
pin_a2_direction = output
pin_a3_direction = output

-- include library & turn outputs on
include shift_register_74595
sr_output_enable(1)  ; activate shift register outputs

forever loop

   -- set one output of each shift register
   sr_write(1)   ; data for 74595 #3 (end of chain)
   sr_write(2)   ; data for 74595 #2 (middle one)
   sr_write(4)   ; data for 74595 #1 (directly connected to PIC)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- show numbers on seven segment display, connected to shift register
   sr_write(seven_from_digit(1))
   sr_write(seven_from_digit(2))
   sr_write(seven_from_digit(3))
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- clear outputs of all 3 shift registers
   sr_write(0)
   sr_write(0)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- set all outputs of shift register #1
   sr_write(255)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #2 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #3 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs are low now)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

end loop

Generated by JALlib CHM Help System | Source: shift_register_74595.jal


sr_output_enable - JALlib Procedures Help

sr_output_enable JALLIB PROCEDURE

Signature

procedure sr_output_enable(bit in enable) is

Description

sr_enable - enable / disable parallel outputs of shift register

Include

To use this procedure, include the library:

include shift_register_74595

Parameters

  • enable - bit in

Return Value

None

Example

From sample file: 18f67j50_sr_74595.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for 74595 shift register
--
-- Author: Joep Suijs, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    test setup: 3 x 74595 cascaded
--    sr_sda connects to SER_IN / DS pin of 74595 #1
--    SER_OUT / Q7S of 74595 #1 connects to SER_IN / DS pin of 74595 #2
--    SER_OUT / Q7S of 74595 #2 connects to SER_IN / DS pin of 74595 #3
--    sr_scl is connected the SRCK / SHCP pin of all three 74595 chips
--    sr_rck is connected the RCK / STCP pin of all three 74595 chips
--    sr_g is connected the G / OE pin of all three 74595 chips
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_sr_74595.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

enable_digital_io() -- disable analog I/O (if any)

include delay
include seven_segment

-- define IO pin's
alias sr_rck   is pin_a0   ; RCK (parallel clock / load, rising edge)
alias sr_sda   is pin_a1   ; SER_IN   / DS
alias sr_scl   is pin_a2   ; SRCK  (serial clock, rising egde)
alias sr_g     is pin_a3   ; G (output enable, low = enable)

-- set IO pins to output
pin_a0_direction = output
pin_a1_direction = output
pin_a2_direction = output
pin_a3_direction = output

-- include library & turn outputs on
include shift_register_74595
sr_output_enable(1)  ; activate shift register outputs

forever loop

   -- set one output of each shift register
   sr_write(1)   ; data for 74595 #3 (end of chain)
   sr_write(2)   ; data for 74595 #2 (middle one)
   sr_write(4)   ; data for 74595 #1 (directly connected to PIC)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- show numbers on seven segment display, connected to shift register
   sr_write(seven_from_digit(1))
   sr_write(seven_from_digit(2))
   sr_write(seven_from_digit(3))
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- clear outputs of all 3 shift registers
   sr_write(0)
   sr_write(0)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- set all outputs of shift register #1
   sr_write(255)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #2 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #3 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs are low now)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

end loop

Generated by JALlib CHM Help System | Source: shift_register_74595.jal


sr_write - JALlib Procedures Help

sr_write JALLIB PROCEDURE

Signature

procedure sr_write(byte in data) is

Description

sr_write - write one byte of data to chip

Include

To use this procedure, include the library:

include shift_register_74595

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 18f67j50_sr_74595.jal

-- ----------------------------------------------------------------------------
-- Title: Test program for 74595 shift register
--
-- Author: Joep Suijs, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Testing lcd_backlight
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- Sources:
--
-- Notes:
--    test setup: 3 x 74595 cascaded
--    sr_sda connects to SER_IN / DS pin of 74595 #1
--    SER_OUT / Q7S of 74595 #1 connects to SER_IN / DS pin of 74595 #2
--    SER_OUT / Q7S of 74595 #2 connects to SER_IN / DS pin of 74595 #3
--    sr_scl is connected the SRCK / SHCP pin of all three 74595 chips
--    sr_rck is connected the RCK / STCP pin of all three 74595 chips
--    sr_g is connected the G / OE pin of all three 74595 chips
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f67j50_ms.jal
--    * test : test_sr_74595.jal
--

;@jallib section chipdef
-- chip setup
include 18f67j50                   -- target PICmicro
--
-- Compiler directives
pragma target CLOCK    48_000_000  -- CPU frequency
--
-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT_PLL      -- internal oscillator
                                                -- and using PLL
pragma target PLLDIV   P2          -- reduce OSC 20->4 MHz for PLL input
pragma target CPUDIV   P1          -- CPU freq. from PLL(96/2): 48 MHz
pragma target FCMEN    DISABLED    -- no fail-safeclock monitoring
pragma target IESO     DISABLED    -- no in/ext oscillator switchover
pragma target WDT      CONTROL     -- watchdog software controlled
pragma target XINST    DISABLED    -- not supported by JalV2
pragma target DEBUG    DISABLED    -- no debugging

WDTCON_SWDTEN = OFF                 -- disable watchdog

-- Note: Not specified:
--       Code protection, Boot Block Code protection, Data EEPROM protection,
--       Write protection, Configuration Memory write protection,
--       Table Read protection, Boot Block Table Read protection,
--       and maybe some other configuration bits.
--
OSCCON_SCS = 0b00                  -- select primary clock source
OSCTUNE_PLLEN = enabled            -- activate PLL module
--
WDTCON_SWDTEN = OFF                -- disable WDT
--
_usec_delay (1_000)                -- allow PLL to stabilize

enable_digital_io() -- disable analog I/O (if any)

include delay
include seven_segment

-- define IO pin's
alias sr_rck   is pin_a0   ; RCK (parallel clock / load, rising edge)
alias sr_sda   is pin_a1   ; SER_IN   / DS
alias sr_scl   is pin_a2   ; SRCK  (serial clock, rising egde)
alias sr_g     is pin_a3   ; G (output enable, low = enable)

-- set IO pins to output
pin_a0_direction = output
pin_a1_direction = output
pin_a2_direction = output
pin_a3_direction = output

-- include library & turn outputs on
include shift_register_74595
sr_output_enable(1)  ; activate shift register outputs

forever loop

   -- set one output of each shift register
   sr_write(1)   ; data for 74595 #3 (end of chain)
   sr_write(2)   ; data for 74595 #2 (middle one)
   sr_write(4)   ; data for 74595 #1 (directly connected to PIC)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- show numbers on seven segment display, connected to shift register
   sr_write(seven_from_digit(1))
   sr_write(seven_from_digit(2))
   sr_write(seven_from_digit(3))
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- clear outputs of all 3 shift registers
   sr_write(0)
   sr_write(0)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- set all outputs of shift register #1
   sr_write(255)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #2 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs of #3 become high)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

   -- shift all data to nex shift register, clear outputs of shift register #1,
   -- (all outputs are low now)
   sr_write(0)
   sr_commit()   ; clock all data to outputs
   delay_1ms(1000);

end loop

Generated by JALlib CHM Help System | Source: shift_register_74595.jal


sram_23k256.jal - JALLIB Library Documentation

sram_23k256.jal JALLIB LIBRARY

Title

23K256 sram library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by: Sebastien Lelong

Compiler

>=2.4l

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This is library for 23K256 SPI SRAM, Microchip's 20mhz 256kbit SRAM memory

Notes

Address from 0 to 32,767
This is a 2.7v to 3.6v memory.
This lib should also work with 23k640 (64kbit sram), but hasn't been tested, please let me know.
Also should work with 23A640 & 23A256 (1.5v to 1.95v versions), also not tested
SPI Mode is 00 for 23k256
Array Usage:
If you are using a procedure that reads/write more then one byte you must
set SEQUENTIAL_MODE & must use the chip select pin.
Set mode before each read/write. Must be TRUE if more then one device is
on bus using different spi modes.

constants for use with init procedure input data
modes in witch to read and write data

Sources

http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
Functions descriptions:
sram_23k256_init - initialize startup settings & spi mode 00
sram_23K256_read_settings - Reads the settings register to get the current 23k256 mode
sram_23K256_write - Write one byte to selectd address
sram_23K256_read - Read one byte to selectd address
sram_23K256_byte[address] - Use as a 32K byte array
sram_23K256_word[address] - Use as a 16K word array
sram_23K256_dword[address] - Use as a 8K dword array
sram_23K256_start_write - get 23K256 ready for writing and
select a address to start from (fast writes)
sram_23K256_do_write - write byte to the 23K256
sram_23K256_stop_write - tell 23K256 you are finished writing
sram_23K256_start_read - get 23K256 ready for reading and
select a address to start from (fast reads)
sram_23K256_do_read - read byte from the 23K256
sram_23K256_stop_read - tell 23K256 you are finished reading

Constants and Variables

SRAM_23K256_BYTE_MODE - const byte = 0b00 -- read only one byte
read only one byte
SRAM_23K256_SEQUENTIAL_MODE - const byte = 0b01 -- send read command then read many bytes
send read command then read many bytes
SRAM_23K256_PAGE_MODE - const byte = 0b10 -- send read command then read 1 32Byte page
send read command then read 1 32Byte page
SRAM_23K256_HOLD_DISABLE - const byte = 1 -- disable the hold pin. (connect put pin direct to 3.3v)
disable the hold pin. (connect put pin direct to 3.3v)
SRAM_23K256_HOLD_ENABLE - const byte = 0 -- enable the hold pin (conect pin to microcontroller)
enable the hold pin (conect pin to microcontroller)
SRAM_23K256_READ_COMMAND - const byte = 0b_0000_0011 -- Read data from memory array beginning at selected address
Read data from memory array beginning at selected address
SRAM_23K256_WRITE_COMMAND - const byte = 0b_0000_0010 -- Write data to memory array beginning at selected address
Write data to memory array beginning at selected address
SRAM_23K256_READ_STATUS - const byte = 0b_0000_0101 -- Read STATUS register
Read STATUS register
SRAM_23K256_WRITE_SETTINGS - const byte = 0b_0000_0001 -- Write STATUS register
Write STATUS register

Routines

  • sram_23k256_byte'get - Function returns byte
  • sram_23k256_byte'put - Procedure
  • sram_23k256_do_read - Procedure
  • sram_23k256_do_write - Procedure
  • sram_23k256_dword'get - Function returns dword
  • sram_23k256_dword'put - Procedure
  • sram_23k256_init - Procedure
  • sram_23k256_read - Procedure
  • sram_23k256_read_settings - Procedure
  • sram_23k256_start_read - Procedure
  • sram_23k256_start_write - Procedure
  • sram_23k256_stop_read - Procedure
  • sram_23k256_stop_write - Procedure
  • sram_23k256_word'get - Function returns word
  • sram_23k256_word'put - Procedure
  • sram_23k256_write - Procedure


sram_23k256_do_read - JALlib Procedures Help

sram_23k256_do_read JALLIB PROCEDURE

Signature

procedure sram_23k256_do_read(byte out data) is

Description

read byte from the 23K256

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • data - byte out

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_do_write - JALlib Procedures Help

sram_23k256_do_write JALLIB PROCEDURE

Signature

procedure sram_23k256_do_write(byte in data) is

Description

write byte to the 23K256
you may use spi_master directly instead.

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • data - byte in

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_init - JALlib Procedures Help

sram_23k256_init JALLIB PROCEDURE

Signature

procedure sram_23k256_init(byte in sram_23k256_mode, byte in sram_23k256_hold_disable) is

Description

initialize startup settings & spi mode 00

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • sram_23k256_mode - byte in
  • sram_23k256_hold_disable - byte in

Return Value

None

Example

From sample file: 18f67j50_fat32_pata_hard_disk.jal

-- Title: FAT32 library for reading fat32 filesystem
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this example reads files & folders from a fat32 formatted sd card
--              using the fat32 library.
--
-- Sources:
-- http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
-- http://www.pjrc.com/tech/8051/ide/fat32.html
-- http://en.wikipedia.org/wiki/File_Allocation_Table
--
-- This file has been generated by Matt's sample generator.
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

const PRINT_MAX_VAR_SIZE = 6
include print
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_c2
ALIAS sram_23k256_chip_select_direction   is pin_c2_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- procedure for sending 80 "-----------------" via serial port
procedure separator() is
   serial_data = 13
   serial_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_data, str3)
   print_crlf(serial_data)
end procedure

-- start of main program
separator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

separator() -- send "-----" and go to next example

---------------------------------------------------------------------------------------------------------------
-- example read filename, send it via serial port
------------------------------------------------------------

-- we are still in the root dir of the 1st partition

;fat32_read_file_info(2) -- read 2nd file's name, location, size, attributes into memory

-- now send the filename via the serial port
;fat32_print_file_info(serial_data,FAT32_PRINT_NUMBER + FAT32_PRINT_LONG_FILE_NAME)

------------------------------------------------------------
-- example user interaction,
-- send file/dir number via serial port to go into it
--
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into file and read it
------------------------------------------------------------

var byte data
var dword step1
var word step2

var byte file_number2 = 0
forever loop
   separator() -- send "-----" then loop and wait for user input

   -- this is not needed serial_sw.
   -- serial_data_available doesn't exist on serial sw.
   if defined(serial_data_available) then
      while !serial_data_available loop
      end loop
   end if

   file_number2 = serial_data

   -- choose a file for reading or dir for opening
   if fat32_cd(file_number2) then             -- if change directory is successful
      fat32_print_directory(serial_data, FAT32_PRINT_ALL) -- sends dir listing via serial port (with file numbers)
   elsif fat32_file_open(file_number2) then   -- if go into file is successful

      -- calculate number of sectors in file
      var dword sectors_available
      if (fat32_file_size) == (fat32_file_size / 512) * 512 then
         sectors_available = (fat32_file_size / 512)
      else
         sectors_available = (fat32_file_size / 512) + 1
      end if

;      -- EXAMPLE 1 READ (slowest and user friendly)
;      -- Read any byte number in the file, in any order you wish.
;      for fat32_file_size using step1 loop
;          data = fat32_read_file_byte_address(step1)
;          serial_data = data
;      end loop
;
      -- EXAMPLE 2 READ (slow, not so user friendly)
      -- You must start reading from the beginning of the file, and
      -- read sectors in order.
;      fat32_start_file_read ()
;      for fat32_file_size loop
;          data = fat32_read_file_byte()
;          serial_data = data
;      end loop
;      fat32_stop_file_read()

      -- EXAMPLE 3 WRITE (fast and user friendly, suggested use)
      -- Read from any sector number in the file, in any order you wish.
;      for sectors_available using step1 loop
;
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "E"
;         end loop
;
;         -- write one sector to the disk
;         fat32_write_file_sector_number(step1)
;      end loop
      --
      -- EXAMPLE 3 READ (fast and user friendly)
      -- Read from any sector number in the file, in any order you wish.
      for sectors_available using step1 loop
         -- read one sector from the disk
         fat32_read_file_sector_number(step1)
         -- send the sector via serial port
         for 512 using step2 loop
            serial_data = fat32_sector_buffer[step2]
         end loop
      end loop

;      -- EXAMPLE 4 WRITE (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_write ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- set the data to be written
;         for 512 using step2 loop
;            fat32_sector_buffer[step2] = "D"
;         end loop
;         -- write one sector to the disk
;         fat32_write_file_sector()
;         -- send the sector via serial port
;      end loop
;      fat32_stop_file_write() -- end of file, set media idle
;      --
;      --
;      -- EXAMPLE 4 READ (fastest, not so user friendly)
;      -- Read sectors from a file. You must start reading from
;      -- the beginning of the file, and read sectors in order.
;      fat32_start_file_read ()  -- go in the file, get ready to read
;      for ((fat32_file_size / 512) + 1) using step1 loop
;         -- read one sector from the disk
;         fat32_read_file_sector()
;         -- send the sector via serial port
;         for 512 using step2 loop
;            serial_data = fat32_sector_buffer[step2]
;         end loop
;      end loop

      fat32_file_close()
   end if
end loop

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_read - JALlib Procedures Help

sram_23k256_read JALLIB PROCEDURE

Signature

procedure sram_23k256_read(word in address, byte out data) is

Description

Read 1 byte to selected address

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • address - word in
  • data - byte out

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_read_settings - JALlib Procedures Help

sram_23k256_read_settings JALLIB PROCEDURE

Signature

procedure sram_23k256_read_settings(byte out mode, byte out hold_is_disabled) is

Description

Reads the status/settings register to get the current 23k256 mode
that was previously set in the init procedure.
SRAM_23K256_BYTE_MODE, SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_PAGE_MODE

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • mode - byte out
  • hold_is_disabled - byte out

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_start_read - JALlib Procedures Help

sram_23k256_start_read JALLIB PROCEDURE

Signature

procedure sram_23k256_start_read(word in address) is

Description

get 23K256 ready for reading and select a address to start from (fast reads)
do not interupt read process by switching to another spi device

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • address - word in

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_start_write - JALlib Procedures Help

sram_23k256_start_write JALLIB PROCEDURE

Signature

procedure sram_23k256_start_write(word in address) is

Description

get 23K256 ready for writing and select a address to start from (fast writes)
do not interupt read process by switching to another spi device

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • address - word in

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_stop_read - JALlib Procedures Help

sram_23k256_stop_read JALLIB PROCEDURE

Signature

procedure sram_23k256_stop_read() is

Description

tell 23K256 you are finished reading

Include

To use this procedure, include the library:

include sram_23k256

Parameters

None

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_stop_write - JALlib Procedures Help

sram_23k256_stop_write JALLIB PROCEDURE

Signature

procedure sram_23k256_stop_write() is

Description

tell 23K256 you are finished writing

Include

To use this procedure, include the library:

include sram_23k256

Parameters

None

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


sram_23k256_write - JALlib Procedures Help

sram_23k256_write JALLIB PROCEDURE

Signature

procedure sram_23k256_write(word in address, byte in data) is

Description

Write 1 byte to selected address

Include

To use this procedure, include the library:

include sram_23k256

Parameters

  • address - word in
  • data - byte in

Return Value

None

Example

From sample file: 16f877a_23k256.jal

-- Title: 23k256 sram example
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This library provides example usage for 23k256 sram
--
-- includes examples for:             : initalize
--                                    : read settings from status register
--                                    : write address
--                                    : read address
--                                    ; Do a large fast write
--                                    ; Do a large fast read
--                                    : Use as a 32K byte array
--                                    : Use as a 16K word array
--                                    : Use as a 8K dword array
--
-- Sources:
-- http://ww1.microchip.com/downloads/en/DeviceDoc/22100D.pdf
-- http://www.microchip.com/stellent/groups/techpub_sg/documents/devicedoc/en026368.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 16f877a                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- example: read the settings that where selected during init
var byte mode, hold_is_disabled
sram_23k256_read_settings (mode, hold_is_disabled)

serial_write (mode)                -- send mode to serial port
serial_write (hold_is_disabled)    -- send hold value (true 1 or false 0)

-- example write then read from address 1
sram_23k256_write(1,0xAA)   -- write byte

var byte data1
sram_23k256_read (1, data1) -- read byte

-- send result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- Example using 23k256 as a 32KByte array (at array address 2)
sram_23k256_byte[2] = 0xBB   -- set array byte 2 to value 0xBB
data1 = sram_23k256_byte[2]  -- read array dword 2, data2 should = 0xBB

-- send byte result via serial port
serial_write (data1)
serial_write (data1)
serial_write (data1)
serial_write (data1)

-- procedure for sending dword via serial port
procedure SEND_DWORD(DWORD in dval1) is
  var byte dval2[4] at dval1
  serial_write (dval2[3])
  serial_write (dval2[2])
  serial_write (dval2[1])
  serial_write (dval2[0])
end procedure

-- Example using 23k256 as a 8K dword array
var dword data2
sram_23k256_dword[3] = 0xCCDDEEFF -- set array dword 3 to value 0xCCDDEEFF
data2 = sram_23k256_dword[3]      -- read array dword 3, data2 should = 0xCCDDEEFF

-- send dword result via serial port
send_dword (data2)
send_dword (data2)
send_dword (data2)
send_dword (data2)

-- Example fast write lots of data
sram_23k256_start_write (10)
for 1024 loop
  sram_23k256_do_write (0x11)
end loop
sram_23k256_stop_write()

-- Example fast read lots of data
sram_23k256_start_read (10)
for 1024 loop
  sram_23k256_do_read (data1)
  serial_write (data1)
end loop
sram_23k256_stop_read()

-- send 0xFF to serial port twice
serial_write (0xFF)
serial_write (0xFF)

Generated by JALlib CHM Help System | Source: sram_23k256.jal


ssd1306_clear_screen - JALlib Procedures Help

ssd1306_clear_screen JALLIB PROCEDURE

Signature

procedure ssd1306_clear_screen() is

Description

Clear the screen and move the cursor to position 0,0.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_display_all_on - JALlib Procedures Help

ssd1306_display_all_on JALLIB PROCEDURE

Signature

procedure ssd1306_display_all_on() is

Description

Put all segments of the display on.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_display_inverse - JALlib Procedures Help

ssd1306_display_inverse JALLIB PROCEDURE

Signature

procedure ssd1306_display_inverse() is

Description

Put the display in inverse mode.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_display_normal - JALlib Procedures Help

ssd1306_display_normal JALLIB PROCEDURE

Signature

procedure ssd1306_display_normal() is

Description

Put the display in normal (non-inverse) mode.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_display_off - JALlib Procedures Help

ssd1306_display_off JALLIB PROCEDURE

Signature

procedure ssd1306_display_off() is

Description

Switch the display off.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_display_on - JALlib Procedures Help

ssd1306_display_on JALLIB PROCEDURE

Signature

procedure ssd1306_display_on() is

Description

Put the display on.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_display_resume - JALlib Procedures Help

ssd1306_display_resume JALLIB PROCEDURE

Signature

procedure ssd1306_display_resume() is

Description

Resume the display.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_goto - JALlib Procedures Help

ssd1306_goto JALLIB PROCEDURE

Signature

procedure ssd1306_goto(byte in x, byte in y) is

Description

Set the current position for the data to be written, x = 0->127, y = 0->7.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • x - byte in
  • y - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_init - JALlib Procedures Help

ssd1306_init JALLIB PROCEDURE

Signature

procedure ssd1306_init() is

Description

Initialize the control pins abd the SSD1306. When SPI is used and the reset
pin is defined then the module will also be hardware reset.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_set_contrast - JALlib Procedures Help

ssd1306_set_contrast JALLIB PROCEDURE

Signature

procedure ssd1306_set_contrast(byte in contrast) is

Description

Set display contrast, value from 0x00 to 0xFF.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • contrast - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_set_start_line - JALlib Procedures Help

ssd1306_set_start_line JALLIB PROCEDURE

Signature

procedure ssd1306_set_start_line(byte in start_line) is

Description

Set the display start line. The procedure can be used to implement a
vertical scroll feature. Start line is in range 0..(SSD1306_MAX_Y_PIXELS - 1)

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • start_line - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_start_scroll_diagonal_left - JALlib Procedures Help

ssd1306_start_scroll_diagonal_left JALLIB PROCEDURE

Signature

procedure ssd1306_start_scroll_diagonal_left(byte in start, byte in stop) is

Description

Scroll the whole display diagonal left. For scrolling the whole display
'start' must be 0x00 and 'stop' must be 0x07.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • start - byte in
  • stop - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_start_scroll_diagonal_right - JALlib Procedures Help

ssd1306_start_scroll_diagonal_right JALLIB PROCEDURE

Signature

procedure ssd1306_start_scroll_diagonal_right(byte in start, byte in stop) is

Description

Scroll the whole display diagonal right. For scrolling the whole display
'start' must be 0x00 and 'stop' must be 0x07.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • start - byte in
  • stop - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_start_scroll_left - JALlib Procedures Help

ssd1306_start_scroll_left JALLIB PROCEDURE

Signature

procedure ssd1306_start_scroll_left(byte in start, byte in stop) is

Description

Scroll the whole display left. For scrolling the whole display 'start'
must be 0x00 and 'stop' must be 0x07.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • start - byte in
  • stop - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_start_scroll_right - JALlib Procedures Help

ssd1306_start_scroll_right JALLIB PROCEDURE

Signature

procedure ssd1306_start_scroll_right(byte in start, byte in stop) is

Description

Scroll the whole display right. For scrolling the whole display 'start'
must be 0x00 and 'stop' must be 0x07.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

  • start - byte in
  • stop - byte in

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_stop_scroll - JALlib Procedures Help

ssd1306_stop_scroll JALLIB PROCEDURE

Signature

procedure ssd1306_stop_scroll() is

Description

Stop the scroll feature.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


ssd1306_update_display - JALlib Procedures Help

ssd1306_update_display JALLIB PROCEDURE

Signature

procedure ssd1306_update_display() is

Description

Copy the changed area of the cache to the lcd. This procedure is to be
used when using graphics features like pixes, lines, circles, etc. and is
not available in text only mode.

Include

To use this procedure, include the library:

include glcd_ssd1306

Parameters

None

Return Value

None

Example

From sample file: 16f18857_glcd_ssd1306_font_graphics.jal

-- -----------------------------------------------------------------------------
-- Title: GLCD SSD1306 demo sample showing text and pixel based graphics.
-- Author: Rob Jansen, Copyright (c) 2020..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Demo program showing how to use GLCD SSD1306. It demonstrates
--              all features of the glcd_ssd1360.jal library. This sample shows
--              both the text (font usage) features as well as the graphics
--              features drawing a line, a boxe, a circle and an ellipse.
--              Last but not least it shows the drawing of images including
--              an animation of a charging battery.
--
-- Notes: A way to generate the image array from a png or jpg file:
--        *) Go to: http://javl.github.io/image2cpp/
--        *) Upload your png of jpg file
--        *) Canvas size: 128 x 64 or smaller, depending on your application
--        *) Background color: Black
--        *) Invert image colors: Yes (tick)
--        *) Scaling: scale to fit, keep proportions
--        *) Brightness: 128 or higher (what suits you best)
--        *) Code output format must be: Plain bytes
--        *) Draw mode must be: Vertical - 1 bit per pixel
--
--       For a text only version that uses IIC see the sample file
--       16f1825_glcd_ssd1306_font.jal.
--

include 16f18857
pragma target clock 20_000_000      -- oscillator frequency
pragma target OSC      HS           -- crystal or resonator
pragma target RSTOSC   EXT1X        -- power-up clock select: OSC
pragma target CLKOUTEN DISABLED     -- no clock output
pragma target WDT      DISABLED     -- watchdog
pragma target BROWNOUT DISABLED     -- no brownout reset
pragma target FCMEN    DISABLED     -- no clock monitoring
pragma target CSWEN    ENABLED      -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED      -- use low voltage programming
pragma target MCLR     EXTERNAL     -- external reset

-- This program uses the internal oscillator at 4 MHz.
;pragma target clock    4_000_000       -- oscillator frequency
--
;pragma target OSC      OFF                       -- internal oscillator
;pragma target RSTOSC   HFINT32                   -- select 32 MHz
;pragma target CLKOUTEN DISABLED                  -- no clock output
;pragma target WDT      DISABLED                  -- watchdog
;pragma target BROWNOUT DISABLED                  -- no brownout reset
;pragma target FCMEN    DISABLED                  -- no clock monitoring
;pragma target CSWEN    ENABLED                   -- allow writing OSCCON1 NOSC and NDIV
;pragma target LVP      ENABLED                   -- low voltage programming
;pragma target MCLR     EXTERNAL                  -- external reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
;OSCFRQ_HFFRQ = 0b010                -- Fosc 32 -> 4 MHz
--

enable_digital_io()
-- Wait some time for the hardware to power up.
_usec_delay(100_000)

-- The default display resolution is 128 x 64. When using 128 x 32 define:
-- const SSD1306_Y_32_PIXELS = TRUE

-- In this sample program you can select between IIC or SPI communication.
-- const USE_IIC = TRUE -- When commenting this out, the program will use SPI.
if defined(USE_IIC) then
   -- Using IIC, include and initialize IIC.
   const word _i2c_bus_speed = 4 -- 400kHz (set to 1 gives 100 kHz)
   const bit _i2c_level = TRUE   -- i2c levels (not SMB)
   alias i2c_scl is pin_C3
   alias i2c_scl_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias i2c_sda is pin_C4
   alias i2c_sda_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   include i2c_hardware
   i2c_initialize()
else
   -- Using SPI.
   ; Define the required SPI pins.
   alias ssd1306_sck is pin_C3                     -- To D0 of SSD1306
   alias ssd1306_sck_direction is pin_C3_direction -- Pin 14 of 28 pin DIP
   alias ssd1306_sdo is pin_C4                     -- To D1 of SSD1306
   alias ssd1306_sdo_direction is pin_C4_direction -- Pin 15 of 28 pin DIP
   alias ssd1306_csn is pin_C2                     -- To CS of SSD1306
   alias ssd1306_csn_direction is pin_C2_direction -- Pin 13 of 28 pin DIP
   alias ssd1306_dc is pin_C1                      -- To DC of SSD1306
   alias ssd1306_dc_direction is pin_C1_direction  -- Pin 12 of 28 pin DIP
   -- The SPI version of the SSD1306 uses a hardware reset pin for its reset.
   -- This optional feature can be used by defining the following:
   alias ssd1306_res is pin_c0                      -- To RES of SSD1306
   alias ssd1306_res_direction is pin_c0_direction  -- Pin 11 of 28 pin DIP

   -- You can use software SPI too by setting this constant.
   -- const SSD1306_SOFTWARE_SPI = TRUE
   if !defined(SSD1306_SOFTWARE_SPI) then
      -- Using SPI hardware and initiallize.
      include spi_master_hw
      spi_init(SPI_MODE_00, SPI_RATE_FOSC_16)
   end if
end if

-- Set the pinning for the hardware pins of IIC or SPI. This is default but
-- still needed for this chip. Do not use when using software SPI since it
-- the pins are then assigned for hardware SPI.
if !defined(SSD1306_SOFTWARE_SPI) then
   include pps
   pps_control_lock(FALSE)
   RC4PPS = PPS_SDA1  -- SDA re-assigned to C4  (default)
   RC3PPS = PPS_SCK1  -- SCK re-assigned to C3  (default)
   pps_control_lock(TRUE)
end if

include delay
include print

-- Font libraries.
include glcd_6x8_font
include glcd_12x16_font
include glcd_font

-- Include and initialize the GLCD lib. This will also initialize the IIC or
-- SPI interface.
include glcd_ssd1306
ssd1306_init()

-- Definition of some images.
-- Marilyn Monroe 84 x 48
const byte marilyn[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x38, 0x18, 0x18, 0x08,
    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x18, 0x78, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe8, 0x40, 0x00, 0x00, 0x20, 0xc0, 0xc0, 0x80,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7e, 0xfe,
    0x62, 0x63, 0x61, 0xc3, 0xc3, 0xc3, 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x10,
    0x38, 0x18, 0x18, 0x30, 0x30, 0x30, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf4, 0x7c,
    0xfc, 0xe0, 0xf7, 0x77, 0x3f, 0x3e, 0x38, 0xb0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc7, 0x03, 0x07, 0x3f, 0x03, 0x03, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x30, 0x30, 0x60, 0x70, 0x70, 0xfc, 0xff,
    0xc3, 0x00, 0x02, 0x02, 0x06, 0x06, 0x0c, 0x1c, 0x1c, 0x3e, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x0b, 0x01, 0x81, 0xb0, 0x20, 0xf0, 0xe7, 0xf7, 0xef, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0xf1, 0xf8, 0xf0,
    0xfc, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xf7, 0xf3, 0xf3, 0xf3, 0xf3, 0xf4, 0xe6,
    0xee, 0xce, 0xfc, 0xfc, 0xf8, 0xf0, 0x00, 0x08, 0x00, 0xe0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xdf, 0x98, 0xe2, 0x84, 0xff, 0xff, 0xfd, 0xbf,
    0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2,
    0xf7, 0x67, 0x4f, 0xff, 0xff, 0xff, 0xfe, 0xe0, 0x80, 0x00, 0x00, 0x03, 0x03, 0x07, 0x07, 0x04,
    0x04, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x07, 0x83, 0x81, 0xc0, 0x80, 0xc8, 0xe6, 0xf3, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0x3f, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x03, 0x07, 0x06, 0x06, 0x06, 0x0f, 0x0f, 0x0f, 0x00, 0x07, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
    0x1f, 0x1f, 0x1f, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- JAL Logo 84 x 48
const byte jal_logo[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0,
    0xc0, 0x40, 0x58, 0xf8, 0xfe, 0xf8, 0x9c, 0x9c, 0x94, 0xf4, 0x7c, 0xd4, 0xd4, 0x7c, 0x78, 0xc8,
    0xcc, 0xac, 0x6c, 0xd8, 0xf0, 0x60, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xf0, 0x70, 0x5e, 0xcf,
    0x83, 0x85, 0xce, 0x76, 0x1f, 0x8f, 0xc7, 0x43, 0x44, 0x1e, 0x34, 0x05, 0x08, 0x10, 0x20, 0x40,
    0x60, 0x40, 0xc0, 0x40, 0x40, 0x40, 0x23, 0x1c, 0x01, 0x83, 0x8f, 0xff, 0xff, 0xe3, 0xe0, 0xf0,
    0xf0, 0xf0, 0x70, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x62, 0x82, 0x01, 0x01, 0x71, 0xf1, 0x98, 0x98, 0xfc, 0xdc, 0xfc,
    0xee, 0xfe, 0xfe, 0x7f, 0x7f, 0x3f, 0x1b, 0x1c, 0xdf, 0x8f, 0x06, 0x0c, 0x30, 0xc0, 0x80, 0x80,
    0x80, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x20, 0xb0, 0xf0, 0xf0, 0xf8, 0xfe, 0xfe, 0x7f, 0x7f, 0xff,
    0xf7, 0xe7, 0xe7, 0xea, 0xf0, 0xe0, 0xe0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x38, 0xf8, 0xff,
    0xfb, 0xff, 0x6f, 0x3f, 0x3f, 0x1d, 0x08, 0x00, 0x00, 0x00, 0xf0, 0x7e, 0x1f, 0x07, 0x03, 0x06,
    0x0f, 0x0f, 0x0f, 0x0f, 0x1f, 0x3f, 0x7f, 0xfd, 0xfa, 0xfd, 0xff, 0xff, 0xf3, 0xfb, 0xf9, 0xfd,
    0xfc, 0xff, 0x7f, 0xff, 0xff, 0x3f, 0x7f, 0x7e, 0x7e, 0x7e, 0x1e, 0x1f, 0x07, 0x0f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x06, 0x0f, 0x0f, 0x1c, 0x1c, 0xde, 0x5e, 0xde, 0x9c, 0x9c, 0x9c, 0x9c, 0x1f, 0x0f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, 0x0f, 0x07,
    0x07, 0x01, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03,
    0x03, 0x07, 0x06, 0x07, 0x07, 0x0f, 0x07, 0x06, 0x07, 0x0f, 0x03, 0x0f, 0x0f, 0x0d, 0x0f, 0x0f,
    0x06, 0x06, 0x00, 0x00, 0x1f, 0x1f, 0x0f, 0x01, 0x0f, 0x03, 0x00, 0x18, 0x19, 0x0f, 0x1e, 0x0e,
    0x08, 0x1f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
-- Battery 0%, 84x48px
const byte battery_00[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 25%, 84x48px
const byte battery_25[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 50%, 84x48px
const byte battery_50[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 75%, 84x48px
const byte battery_75[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78,
    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Battery 100%, 84x48px
const byte battery_100[] = {
    0x00, 0x00, 0xe0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
    0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x7c, 0xf8, 0xf8, 0xf0, 0xc0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
    0xff, 0xff, 0xf0, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
    0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0x0f, 0x0f,
    0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x3c, 0x78, 0x79, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x78, 0x79, 0x79,
    0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x78, 0x78, 0x3c, 0x3f, 0x1f,
    0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Image erase the full area of the image, 128x48px
const byte image_erase[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

-- Arrow, 24x24px
const byte arrow[] = {
    0xf8, 0xfc, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x06,
    0x86, 0xe6, 0x76, 0x3c, 0x08, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80,
    0x00, 0x07, 0x0f, 0x18, 0x0c, 0x0e, 0x06, 0x03, 0x01, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
    0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x03, 0x01
}

-- Envelope, 24x24px
const byte envelope[] = {
    0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x03, 0x03, 0x03, 0x06, 0x0c,
    0x0c, 0x18, 0x30, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xff, 0x07, 0x06, 0x0c, 0x18, 0x18, 0x30, 0x60,
    0xc0, 0xc0, 0xc0, 0x40, 0x40, 0xc0, 0xc0, 0xc0, 0x60, 0x30, 0x18, 0x18, 0x0c, 0x06, 0x07, 0xff,
    0xff, 0xe0, 0xe0, 0xf0, 0x98, 0x8c, 0x86, 0x83, 0x83, 0x81, 0x80, 0x80, 0x80, 0x80, 0x81, 0x83,
    0x83, 0x86, 0x8c, 0x98, 0xf0, 0xe0, 0xe0, 0xff
}

-- Erase the space used by the images. It keeps the top lines 16 of the display.
procedure erase_image_space() is
   glcd_draw_image(image_erase,0,16,128,48)
   ssd1306_update_display()
end procedure

-- Draw the given image and wait some time.
procedure draw_an_image(byte in image[]) is
   erase_image_space()
   glcd_draw_image(image,25,16,84,48)
   ssd1306_update_display()
   delay_1s(3)
end procedure

-- Show a battery charging.
procedure draw_battery_charging() is
   erase_image_space()
     for 3 loop
      glcd_draw_image(battery_00,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_25,30,16,84,48)
      ssd1306_update_display()
        _usec_delay(250_000)
      glcd_draw_image(battery_50,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_75,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
      glcd_draw_image(battery_100,30,16,84,48)
      ssd1306_update_display()
       _usec_delay(250_000)
    end loop
end procedure

-- Show two icons drawn independently.
procedure draw_two_icons() is
   erase_image_space()
    for 4 loop
      glcd_draw_image(envelope,30,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(envelope,70,25,24,24)
      ssd1306_update_display()
      _usec_delay(500_000)
      glcd_draw_image(arrow,30,25,24,24)
      ssd1306_update_display()
     _usec_delay(500_000)
    end loop
end procedure

-- Variable declaration.
var byte x

forever loop

   -- First write the demo text.
   ssd1306_clear_screen()
   glcd_font_use(FONT_6X8)
   ssd1306_goto(22,0)
   print_string(glcd,"JAL SSD1306")
   ssd1306_goto(20,1)
   print_string(glcd,"Library Demo")
   ssd1306_goto(30,4)
   print_string(glcd,"2025-09-25")
   ssd1306_goto(15,5)
   print_string(glcd,"Text & Graphics")
   ssd1306_goto(32,6)
   print_string(glcd,"Font 6x8")
   delay_1s(3)

   -- Goto test. Show all corners.
   glcd_font_use(FONT_6X8)
   -- Top left.
   ssd1306_goto(0,0)
   glcd = "8"
   -- Top utmost right for this font size.
   ssd1306_goto(122,0) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   -- Bottom left.
   ssd1306_goto(0,7)
   glcd = "8"
   -- Bottom utmost right for this font size.
   ssd1306_goto(122,7) -- Font is 6 wide so places it to the most right position.
   glcd = "8"          -- at 122 .. 127.
   delay_1s(3)

   ssd1306_clear_screen()
   ssd1306_goto(0,2)

   -- Show big font
   glcd_font_use(FONT_12X16)
   print_string(glcd,"Font 12*16" )
   delay_1s(3)

   -- Continue with 6X8 font.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   glcd_font_use(FONT_6X8)
   print_string(glcd,"Font 6*8")
   delay_1s(1)

   ssd1306_goto(0,3)
   -- we'll print numbers starting with "0" in inverted format.
   x = 48
   -- numbers are printed inverted
   glcd_background_color = GLCD_BLACK
   while x <= 57 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop

   ssd1306_goto(0,4)
   -- now print capital letters and small letters in normal format.
   x = 65  -- this is "A"
   -- not inverted (ie. normal)
   glcd_background_color = GLCD_WHITE
   while x <= 122 loop
      glcd = x
      delay_100ms(1)
      x = x + 1
   end loop
   delay_1s(3)

   ssd1306_goto(0,0)
   print_string(glcd,"Brightness Demo")

   -- Play with the contrast.
   for 255 using x loop
      ssd1306_set_contrast(x)
      _usec_delay(20_000)
   end loop

   -- Show some display features.
   ssd1306_goto(0,0)
   print_string(glcd,"All Segments On   ")
   delay_1s(3)
   ssd1306_display_all_on()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Resume Display    ")
   ssd1306_display_resume()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Inverse Display   ")
   ssd1306_display_inverse()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Normal Display    ")
   ssd1306_display_normal()
   delay_1s(3)
   ssd1306_goto(0,0)
   print_string(glcd,"Display Off and On")
   delay_1s(2)
   ssd1306_display_off()
   delay_1s(2)
   ssd1306_display_on()
   delay_1s(2)

   -- Show some display scroll features.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Right...   ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Left       ")
   delay_1s(2)
   ssd1306_start_scroll_right(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_left(0x00, 0x07)
   delay_1s(8)
   ssd1306_stop_scroll()
   delay_1s(2)

   -- Custom made vertical scroll. There is no automatic vertical scroll
   -- feature supported by the SSD1306 but we can use the set start line
   -- function to create one.
   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Up ...     ")
   ssd1306_goto(0,1)
   print_string(glcd,"...and Down       ")
   delay_1s(2)
   -- Up.
   for SSD1306_MAX_Y_PIXELS using x loop
     ssd1306_set_start_line(x)
     delay_1ms(50)
   end loop
   -- Down.
   delay_1s(3)
   x = SSD1306_MAX_Y_PIXELS -1
   for SSD1306_MAX_Y_PIXELS loop
      ssd1306_set_start_line(x)
      x = x - 1
      delay_1ms(50)
   end loop
   delay_1s(2)
   -- Back to normal.
   ssd1306_set_start_line(0)

   ssd1306_goto(0,0)
   print_string(glcd,"Scroll Diagonal...")
   ssd1306_goto(0,1)
   print_string(glcd,"...Right and Left ")
   delay_1s(2)
   ssd1306_start_scroll_diagonal_right(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(1)
   ssd1306_start_scroll_diagonal_left(0x00, 0x07)
   delay_1s(5)
   ssd1306_stop_scroll()
   delay_1s(3)

   -- Do some graphics stuff.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Line       ")
   delay_1s(2)
   glcd_line(10,20,60,40)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Box        ")
   delay_1s(2)
   glcd_box(20,20,80,60)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw a Circle     ")
   delay_1s(2)
   glcd_circle(40,40,20)
   ssd1306_update_display()
   delay_1s(2)

   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw an Ellipse   ")
   delay_1s(2)
   glcd_ellipse(40,30,30,10)
   ssd1306_update_display()
   delay_1s(2)

   -- Draw the images, one default, one inverted.
   ssd1306_clear_screen()
   ssd1306_goto(0,0)
   print_string(glcd,"Draw images       ")
   ssd1306_goto(0,1)
   print_string(glcd,"in normal mode    ")
   delay_1s(2)
    -- Start with default black color.
   glcd_pen_color = GLCD_BLACK
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()

   -- Now display the inverted image.
   ssd1306_goto(0,1)
   print_string(glcd,"in inverse mode   ")
   glcd_pen_color = GLCD_WHITE
   erase_image_space()
   delay_1s(2)
      draw_an_image(jal_logo)
      draw_an_image(marilyn)
      -- Show the battery charging.
   draw_battery_charging()
     -- Show drawing 2 icons drawn independently.
   draw_two_icons()
   glcd_pen_color = GLCD_BLACK

end loop

Generated by JALlib CHM Help System | Source: glcd_ssd1306.jal


sst25vf_chip_erase - JALlib Procedures Help

sst25vf_chip_erase JALLIB PROCEDURE

Signature

procedure sst25vf_chip_erase() is

Description

Erase whole chip

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_chip_ready - JALlib Procedures Help

sst25vf_chip_ready JALLIB FUNCTION

Signature

function sst25vf_chip_ready() return bit is

Description

Ask if chip is ready. 0: chip busy; 1: erase or write is finished

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_erase_4kb_sector - JALlib Procedures Help

sst25vf_erase_4kb_sector JALLIB PROCEDURE

Signature

procedure sst25vf_erase_4kb_sector(byte*3 in address) is

Description

Erase 4kB sector

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

  • address - byte*3 in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_init - JALlib Procedures Help

sst25vf_init JALLIB PROCEDURE

Signature

procedure sst25vf_init() is

Description

Init chip

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_read_dword - JALlib Procedures Help

sst25vf_read_dword JALLIB FUNCTION

Signature

function sst25vf_read_dword(byte*3 in addr) return dword is

Description

Read dword

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

  • addr - byte*3 in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_read_jedec_id - JALlib Procedures Help

sst25vf_read_jedec_id JALLIB PROCEDURE

Signature

procedure sst25vf_read_jedec_id(byte out manufacturer, byte out memory_type, byte out memory_capacity) is

Description

Get JEDEC ID (1B Manufacturer, 1B Memory type, 1B Memory capacity code; see datasheet)

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

  • manufacturer - byte out
  • memory_type - byte out
  • memory_capacity - byte out

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_read_word - JALlib Procedures Help

sst25vf_read_word JALLIB FUNCTION

Signature

function sst25vf_read_word(byte*3 in addr) return word is

Description

Read one word

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

  • addr - byte*3 in

Return Value

word - Function return value

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_write_dword - JALlib Procedures Help

sst25vf_write_dword JALLIB PROCEDURE

Signature

procedure sst25vf_write_dword(byte*3 in addr, dword in data) is

Description

Write dword

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

  • addr - byte*3 in
  • data - dword in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


sst25vf_write_word - JALlib Procedures Help

sst25vf_write_word JALLIB PROCEDURE

Signature

procedure sst25vf_write_word(byte*3 in addr, word in data) is

Description

Write word

Include

To use this procedure, include the library:

include flash_sst25vf

Parameters

  • addr - byte*3 in
  • data - word in

Return Value

None

Example

From sample file: 18f27j53_sst25vf.jal

-- Title: Test of the Microchip Flash SST25VF016 chip with PIC18f27j53
-- Author: Urmas Joeleht, Copyright (c) 2014, 2015, all rights reserved.
-- Adapted-by:
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Sources:
--
-- Description:
-- Sample Microchip (SST) 1...128 Mbit serial flash chip test program for Microchip SST25VFxxx.
--
-- Notes:
--  - File creation date/time: 6 Nov 2014 22:51:19.
-- Led on pin_B0
--

-- -------------------------------------------------------------
include 18f27j53
pragma target clock 48_000_000    -- oscillator frequency
-- magical statements
pragma target PLLDIV    P2
pragma target CPUDIV    P1
pragma target PLLEN     ENABLED
pragma target OSC INTOSC_NOCLKOUT_PLL
--osc = 0x2
--pragma target OSC     HS_PLL   --if external OSC in use
pragma target WDT  CONTROL       -- Disabled - Controlled by SWDTEN bit
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
OSCCON_IRCF = 0b111
OSCCON_SCS = 0b00    -- select primary clock source

pragma target RTCOSC T1OSC
--pragma target SOSCSEL HS_CP
pragma target ADCSEL B12       -- adc 10 or 12 bit select

_usec_delay(2000) -- PLL needs 2ms before stable
-- -------------------------------------------------------------
enable_digital_io()                -- make all pins digital I/O
-- -------------------------------------------------------------
-- Set interrupts so we can react when alarm is ringing
PIE3_RTCCIE = enabled
INTCON_GIE = enabled
INTCON_PEIE = true
--
include delay
include print
include format
-- -----------------------------------------------------------------------------
--SERIAL HW
-- -----------------------------------------------------------------------------

const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()

-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
-- ----------------------------------------------------------
alias   led    is pin_B0
pin_B0_direction =  output
-- ----------------------------------------------------------
-- 18F27J53 uses Peripherial Pin selection, so we have to define
-- which pps (named RPx) pins we use for SPI
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
--
--SPI
   PPS_MAP_RP1  = PPS_SCK2
   PPS_MAP_RP13 = PPS_SDO2
   PPS_MAP_SDI2 = RP0
-- PPS configuration is done, we can lock again
pps_control_lock(true)
-- give more descriptive aliases for RP pins
alias pin_SCK2            is  pin_RP1
alias pin_SCK2_direction  is  pin_RP1_direction
alias pin_SDI2            is  pin_RP0
alias pin_SDI2_direction  is  pin_RP0_direction
alias pin_SDO2            is  pin_RP13
alias pin_SDO2_direction  is  pin_RP13_direction
-- -----------------------------------------------------------
   -- configure SPI to use MSSP2 module
include spi_master_hw2
   pin_sdi2_direction = input    -- spi input
   pin_sdo2_direction = output   -- spi output
   pin_sck2_direction = output   -- spi clock
alias spi_master_hw is spi_master_hw2
alias spi_master_set_mode is spi_master_hw2_set_mode
alias spi_master_set_speed is spi_master_hw2_set_speed
alias spi_master_exchange is spi_master_hw2_exchange
spi2_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
-- ----------------------------------------------------------
-- defying flash chip chip select pin
alias sst25vf_cs is pin_A7
alias sst25vf_cs_direction   is pin_a7_direction
sst25vf_cs_direction = output    -- chip select/slave select pin
sst25vf_cs = high  -- disable chip first
include flash_sst25vf
sst25vf_init()
-- variables for tests
var byte*3 iii  -- variable for addresses
var word test = 0 -- variable for read data (word)
var dword test2 = 0  -- variable for read data (dword)
var dword error_counter = 0 -- variable for counting wrong values in tests
var byte manufacturer, memory_type, memory_capacity -- variables for chip info
var word mem_size -- memory size info
var byte*3 chip_max_address = 0xFFFFFF -- variable for chip max address

--Strings for print to serial
const byte result_str[] = "Errors count: "
const byte manufacturer_str1[]= "Made by Microchip (SST)"
const byte manufacturer_str2[] = "Unknown manufacturer"
const byte mem_type_str1[] = "SS25VF series"
const byte mem_type_str2[] = "Unknown series"
const byte mem_size_str[] = "Memory size "
const byte mem_max_str[] = "Memory max address:  "
const byte erased_str[] = "Chip erased."
const byte testing_str[] = "Testing ..."
const byte reading_str[] = "Reading 4kB"
const byte verifying_str[] = "Verifying ..."
const byte test_str[] = "Test "
const byte filled_str[] = "Fill 4kB with 0xAA "
const byte erased2_str[] = "4kB sector erased"
const byte filled2_str[] = "Fill 4kB with 0x00 "
const byte end_str[] = "All tests finished"
const byte progress_str[] = "0____________________________l00"
-- ----------------------------------------------------------
-- Starting tests. Will be done once, no forever loop.
-- ----------------------------------------------------------

-- ----------------------------------------------------------
-- Test 1. Read Chip ID, Manufacturer, chip size
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "1"
print_crlf(serial_hw_data)
led = 0
sst25vf_read_jedec_id(manufacturer, memory_type, memory_capacity)
if manufacturer == 0xBF then
  print_string(serial_hw_data, manufacturer_str1)  -- Microchip
else
   print_string(serial_hw_data, manufacturer_str2) -- other manufacturer
end if
print_crlf(serial_hw_data)
if memory_type == 0x25 then
  print_string(serial_hw_data, mem_type_str1)
  serial_hw_data = " "
  print_byte_hex(serial_hw_data,memory_type)
else
   print_string(serial_hw_data, mem_type_str2)
end if
print_crlf(serial_hw_data)
case memory_capacity of                           -- change manufacturer memory
   0x8A: block                                    -- size code to real size
            mem_size = 512 -- 0.5M
            chip_max_address = 0x00FFFF
         end block
   0x8B: block
            mem_size = 1   -- 1M
            chip_max_address = 0x01FFFF
         end block
   0x8C: block
            mem_size = 2   -- 2M
            chip_max_address = 0x03FFFF
         end block
   0x8D: block
            mem_size = 4   -- 4M
            chip_max_address = 0x07FFFF
         end block
   0x8E: block
            mem_size = 8   -- 8M
            chip_max_address = 0x0FFFFF
         end block
   0x41: block
            mem_size = 16  -- 16M
            chip_max_address = 0x1FFFFF
         end block
   0x4A: block
            mem_size = 32   -- 32M
            chip_max_address = 0x3FFFFF
         end block
   0x4B: block
            mem_size = 64   -- 64M
            chip_max_address = 0x7FFFFF
         end block
   0x4C: block
              mem_size = 128 -- 128M
              chip_max_address = 0xFFFFFF
            end block
   otherwise
         block
            mem_size = 0
            chip_max_address = 0xFFFFFF
         end block
end case
print_string(serial_hw_data, mem_size_str)            -- printing memory size
serial_hw_data = " "
print_word_dec(serial_hw_data, mem_size)
if mem_size == 512 then
   serial_hw_data = "k"
else
   serial_hw_data = "M"
end if
serial_hw_data = "b"
print_crlf(serial_hw_data)
print_string(serial_hw_data, mem_max_str)
serial_hw_data = " "                                 -- printing memory max size
print_dword_hex(serial_hw_data,chip_max_address)
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(100)
-- ----------------------------------------------------------
--Test 2. Erasing chip and verifying all data, printing result
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str) -- print test number
serial_hw_data = "2"
print_crlf(serial_hw_data)
led = 0
sst25vf_chip_erase()                   -- erase whole chip
while sst25vf_chip_ready()== 0 loop    -- wait when chip is ready after erasing.
end loop                               -- Alternative is wait for 50ms

print_string(serial_hw_data, erased_str)
print_crlf(serial_hw_data)
print_string(serial_hw_data, verifying_str)
print_crlf(serial_hw_data)

led = 1
-- ----------------------------------------------------------
--control, if all data is 0xFF after erase
-- ----------------------------------------------------------
led = 0
print_crlf(serial_hw_data)
print_string(serial_hw_data,progress_str)
print_crlf(serial_hw_data)
for ((chip_max_address + 1) / 2) using iii loop   -- veryfy that whole chip is
   test = sst25vf_read_word(iii*2)                -- after erasing filled with 0xFF
   if iii % ((chip_max_address + 1)/64) == 0 then -- as it can take a lot of time with
      serial_hw_data = "#"                        -- big chips, lets inform user about progress
   end if
   if test != 0xFFFF then
      error_counter = error_counter + 1           -- count errors
   end if
end loop
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)           -- print verifying result
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
led = 1
delay_1ms(2000)                                   -- wait, for reading from screen

-- ----------------------------------------------------------
-- test 4. Read_by word. Reading first 4096 bytes and print to serial
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "3"
print_crlf(serial_hw_data)
print_string(serial_hw_data, reading_str)
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   delay_1ms(1)
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0xAA
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "4"
print_crlf(serial_hw_data)
led = 0
for 2048 using iii loop
   sst25vf_write_word(iii*2,0xAAAA)
end loop
print_string(serial_hw_data, filled_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0xAA
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 2048 using iii loop
   test = sst25vf_read_word(iii*2)
   if (iii%16 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_word_hex(serial_hw_data, test)
   if test != 0xAAAA then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- erase 4kB sector
-- ----------------------------------------------------------
print_string(serial_hw_data, test_str)
serial_hw_data = "5"
print_crlf(serial_hw_data)
sst25vf_erase_4kb_sector(0x00000000)
print_string(serial_hw_data, erased2_str)
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
--controlling 4kB sector
-- ----------------------------------------------------------

for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0xFFFFFFFF then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
-- ----------------------------------------------------------
-- Fill 4kB with 0x00000000 using sst25vf_write_dword()
-- ----------------------------------------------------------
led = 0
for 1024 using iii loop
   sst25vf_write_dword(iii*4,0x00000000)
end loop
print_string(serial_hw_data, filled2_str)
print_crlf(serial_hw_data)
led = 1
delay_1ms(1000)
-- ----------------------------------------------------------
-- Read and verify 4kB with 0x00000000
-- ----------------------------------------------------------
led = 0
print_string(serial_hw_data, reading_str)

print_crlf(serial_hw_data)
for 1024 using iii loop
   test2 = sst25vf_read_dword(iii*4)
   if (iii%8 == 0) then
      print_crlf(serial_hw_data)
   end if
   print_dword_hex(serial_hw_data, test2)
   if test2 != 0x00000000 then
      error_counter = error_counter + 1
   end if
end loop
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
print_string(serial_hw_data,result_str)
print_dword_dec(serial_hw_data, error_counter)
test = 0
error_counter = 0
print_crlf(serial_hw_data)
delay_1ms(1)
led = 1
-- ----------------------------------------------------------
-- All tests done
-- ----------------------------------------------------------
print_string(serial_hw_data, end_str)
print_crlf(serial_hw_data)

Generated by JALlib CHM Help System | Source: flash_sst25vf.jal


stepper_accel - JALlib Procedures Help

stepper_accel JALLIB PROCEDURE

Signature

procedure stepper_accel(word in sec, word in rpm) is

Description

Descr: Determine accelleration ratio
Input: - sec (word) number of 0.1 seconds
- rpm (word) number of 0.1 RPM
Notes: - The stepper speed will increase with # RPMs per 10 ms
For example: with stepper_accel(100,3000)
the stepper accellerates with 300 RPM in 10 seconds (30 RPM/sec)
or accellerate in 2 seconds from 0 to 60 RPM or from 50 to 110 RPM, etc.
- Accelleration (and decelleration) settings are only taken into account
when stepper speed is changed, e.g. with stepper_run() or stepper_stop()
and may be changed any time.

Include

To use this procedure, include the library:

include steppermotor

Parameters

  • sec - word in
  • rpm - word in

Return Value

None

Example

From sample file: 16f1765_steppermotor.jal

-- --------------------------------------------------------------
-- Title: Example of using the stepper library
--
-- Author: Rob Hamerling, Copyright (c) 2016, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Simple stepper motor example with 16f1765
--
-- Sources:
--
-- Notes:
--
-- ----------------------------------------------------------

include 16f1765

-- internal oscillator at 8 MHz (with 4xPLL -> 32 MHz)

pragma target clock     32_000_000           -- Fosc

pragma target OSC       INTOSC_NOCLKOUT
pragma target WDT       DISABLED             -- no watchdog
pragma target PWRTE     ENABLED
pragma target MCLR      EXTERNAL
pragma target BROWNOUT  DISABLED
pragma target CLKOUTEN  DISABLED             -- no clock out
pragma target PPS1WAY   DISABLED
pragma target PLLEN     DISABLED             -- PLL software controlled
pragma target LVP       ENABLED              -- allow Low Voltage Programming

OSCCON_IRCF   = 0b1110                       -- 8 MHz
OSCCON_SCS    = 0b00                         -- clock determined by fuses
OSCCON_SPLLEN = TRUE                         -- PLL (8 -> 32 MHz)

if !defined(T3CON_TMR3CS) then               -- omission in device files
   alias T3CON_TMR3CS is T3CON_CS
end if
if !defined(T3CON_T3SYNC) then
   alias T3CON_T3SYNC is T3CON_SYNC
end if
if !defined(T3CON_T3CKPS) then
   alias T3CON_T3CKPS is T3CON_CKPS
end if

if !defined(T1CON_T1CKPS) then               -- omission in device files
   alias T1CON_T1CKPS is T1CON_CKPS
end if

include delay

alias  stepper_led is pin_A0                 -- led
pin_A0_direction    = OUTPUT

alias  stepper_coils  is  portC_low          -- stepper control
portC_low_direction  = ALL_OUTPUT

const word stepper_steps_per_rotation = 48   -- steps per full rotation

include steppermotor                         -- stepper motor library

-- ------- main program --------

forever loop

   stepper_led = ON
   stepper_cw = TRUE                         -- clockwise
   stepper_fullstep = TRUE                   -- full steps
   stepper_accel(100,1500)                   -- acceleration rate 15 RPM/sec
   stepper_decel(100,1500)                   -- deceleration rate 15 RPM/sec
   stepper_led = ON
   stepper_run(600)                          -- 60 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

   stepper_led = ON
   stepper_cw = FALSE                        -- reverse
   stepper_fullstep = FALSE                  -- half steps
   stepper_accel(100,1000)                   -- acceleration rate 10 RPM/sec
   stepper_decel(100,1000)                   -- deceleration rate 10 RPM/sec
   stepper_led = ON
   stepper_run(300)                          -- 30 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

end loop

Generated by JALlib CHM Help System | Source: steppermotor.jal


stepper_actual_rpm - JALlib Procedures Help

stepper_actual_rpm JALLIB FUNCTION

Signature

function stepper_actual_rpm() return sword is

Description

Descr: Obtain current stepper speed RPM
Returns: The actual RPM in units of 0.1 RPM
A negative value means counter-clockwise rotation

Include

To use this procedure, include the library:

include steppermotor

Parameters

None

Return Value

None

Example

From sample file: 16f1765_steppermotor.jal

-- --------------------------------------------------------------
-- Title: Example of using the stepper library
--
-- Author: Rob Hamerling, Copyright (c) 2016, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Simple stepper motor example with 16f1765
--
-- Sources:
--
-- Notes:
--
-- ----------------------------------------------------------

include 16f1765

-- internal oscillator at 8 MHz (with 4xPLL -> 32 MHz)

pragma target clock     32_000_000           -- Fosc

pragma target OSC       INTOSC_NOCLKOUT
pragma target WDT       DISABLED             -- no watchdog
pragma target PWRTE     ENABLED
pragma target MCLR      EXTERNAL
pragma target BROWNOUT  DISABLED
pragma target CLKOUTEN  DISABLED             -- no clock out
pragma target PPS1WAY   DISABLED
pragma target PLLEN     DISABLED             -- PLL software controlled
pragma target LVP       ENABLED              -- allow Low Voltage Programming

OSCCON_IRCF   = 0b1110                       -- 8 MHz
OSCCON_SCS    = 0b00                         -- clock determined by fuses
OSCCON_SPLLEN = TRUE                         -- PLL (8 -> 32 MHz)

if !defined(T3CON_TMR3CS) then               -- omission in device files
   alias T3CON_TMR3CS is T3CON_CS
end if
if !defined(T3CON_T3SYNC) then
   alias T3CON_T3SYNC is T3CON_SYNC
end if
if !defined(T3CON_T3CKPS) then
   alias T3CON_T3CKPS is T3CON_CKPS
end if

if !defined(T1CON_T1CKPS) then               -- omission in device files
   alias T1CON_T1CKPS is T1CON_CKPS
end if

include delay

alias  stepper_led is pin_A0                 -- led
pin_A0_direction    = OUTPUT

alias  stepper_coils  is  portC_low          -- stepper control
portC_low_direction  = ALL_OUTPUT

const word stepper_steps_per_rotation = 48   -- steps per full rotation

include steppermotor                         -- stepper motor library

-- ------- main program --------

forever loop

   stepper_led = ON
   stepper_cw = TRUE                         -- clockwise
   stepper_fullstep = TRUE                   -- full steps
   stepper_accel(100,1500)                   -- acceleration rate 15 RPM/sec
   stepper_decel(100,1500)                   -- deceleration rate 15 RPM/sec
   stepper_led = ON
   stepper_run(600)                          -- 60 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

   stepper_led = ON
   stepper_cw = FALSE                        -- reverse
   stepper_fullstep = FALSE                  -- half steps
   stepper_accel(100,1000)                   -- acceleration rate 10 RPM/sec
   stepper_decel(100,1000)                   -- deceleration rate 10 RPM/sec
   stepper_led = ON
   stepper_run(300)                          -- 30 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

end loop

Generated by JALlib CHM Help System | Source: steppermotor.jal


stepper_decel - JALlib Procedures Help

stepper_decel JALLIB PROCEDURE

Signature

procedure stepper_decel(word in sec, word in rpm) is

Description

Descr: Determine decelleration ratio
Input: - sec (word) number of 0.1 seconds
- rpm (word) number of 0.1 RPM
Notes: The stepper speed will decrease with # RPMs per 10 ms
See also the notes with stepper_accel()

Include

To use this procedure, include the library:

include steppermotor

Parameters

  • sec - word in
  • rpm - word in

Return Value

None

Example

From sample file: 16f1765_steppermotor.jal

-- --------------------------------------------------------------
-- Title: Example of using the stepper library
--
-- Author: Rob Hamerling, Copyright (c) 2016, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Simple stepper motor example with 16f1765
--
-- Sources:
--
-- Notes:
--
-- ----------------------------------------------------------

include 16f1765

-- internal oscillator at 8 MHz (with 4xPLL -> 32 MHz)

pragma target clock     32_000_000           -- Fosc

pragma target OSC       INTOSC_NOCLKOUT
pragma target WDT       DISABLED             -- no watchdog
pragma target PWRTE     ENABLED
pragma target MCLR      EXTERNAL
pragma target BROWNOUT  DISABLED
pragma target CLKOUTEN  DISABLED             -- no clock out
pragma target PPS1WAY   DISABLED
pragma target PLLEN     DISABLED             -- PLL software controlled
pragma target LVP       ENABLED              -- allow Low Voltage Programming

OSCCON_IRCF   = 0b1110                       -- 8 MHz
OSCCON_SCS    = 0b00                         -- clock determined by fuses
OSCCON_SPLLEN = TRUE                         -- PLL (8 -> 32 MHz)

if !defined(T3CON_TMR3CS) then               -- omission in device files
   alias T3CON_TMR3CS is T3CON_CS
end if
if !defined(T3CON_T3SYNC) then
   alias T3CON_T3SYNC is T3CON_SYNC
end if
if !defined(T3CON_T3CKPS) then
   alias T3CON_T3CKPS is T3CON_CKPS
end if

if !defined(T1CON_T1CKPS) then               -- omission in device files
   alias T1CON_T1CKPS is T1CON_CKPS
end if

include delay

alias  stepper_led is pin_A0                 -- led
pin_A0_direction    = OUTPUT

alias  stepper_coils  is  portC_low          -- stepper control
portC_low_direction  = ALL_OUTPUT

const word stepper_steps_per_rotation = 48   -- steps per full rotation

include steppermotor                         -- stepper motor library

-- ------- main program --------

forever loop

   stepper_led = ON
   stepper_cw = TRUE                         -- clockwise
   stepper_fullstep = TRUE                   -- full steps
   stepper_accel(100,1500)                   -- acceleration rate 15 RPM/sec
   stepper_decel(100,1500)                   -- deceleration rate 15 RPM/sec
   stepper_led = ON
   stepper_run(600)                          -- 60 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

   stepper_led = ON
   stepper_cw = FALSE                        -- reverse
   stepper_fullstep = FALSE                  -- half steps
   stepper_accel(100,1000)                   -- acceleration rate 10 RPM/sec
   stepper_decel(100,1000)                   -- deceleration rate 10 RPM/sec
   stepper_led = ON
   stepper_run(300)                          -- 30 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

end loop

Generated by JALlib CHM Help System | Source: steppermotor.jal


stepper_go - JALlib Procedures Help

stepper_go JALLIB PROCEDURE

Signature

procedure stepper_go(word in steps) is

Description

make a predefined number of steps using accel and decel if defined

Include

To use this procedure, include the library:

include stepper_unipolar_blocking

Parameters

  • steps - word in

Return Value

None

Example

From sample file: 16f630_stepper_unipolar_nonblocking.jal

-- --------------------------------------------------------------------------------------------
-- Title: Example of the Unipolar Stepper Motor with non blocking delays lib with the pic16f630
-- Author: Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved.
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple unipolar stepper motor example lib for Microchip pic16f630,
-- using internal HS 4.0 Mhz XTAL, and internal MCLR, with non blocking delays
-- --
-- Non Blocking delays means that the motor run indepndently of the main program
-- or kind of, it uses the TMR0 feature and interrupts to move the motor.
-- --
-- You must provide a unipolar stepper motor in the pins showed below, and it must
-- be conected to a coil driver like a mosfet*4 or or a darlingtown motor driver
-- --
-- I used a ULN2003 to do the testing job...
-- --
-- You MUST know at least the basic principle of unipolar stepper motors, and
-- know what coil/wire is each one (Common, A, B, C, D), or a method to identify it.
-- See stepper_unipolar_common for more details
--
-- Sources:
-- To many to count, kind of http://www.google.com/?hl=en&q=stepper+motor+tutorial and pick the best?
-- PLEASE read the stepper_unipolar_common lib and the stepper_unipolar_blockin lib for details
--
-- Notes:
-- * This file is maintained by hand!!!
-- --
-- device map
--                 +5 V > VCC [1  U  14] GND < GND
--                         A5 [2     13] A0
--                         A4 [3     12] A1
--                         A3 [4     11] A2
--                   LED < C5 [5     10] C0 > A Coil driver
--                         C4 [6      9] C1 > B Coil driver
--        D Coil Driver <  C3 [7      8] C2 > C Coil driver
-- ------------------------------------------------------
--
include 16f630								-- target PIC device
--
pragma	target clock	4_000_000			-- 4 Mhz is the work freq
pragma	target OSC		INTOSC_NOCLKOUT		-- The PIC uses it's own internal 4Mhz CLOCK
pragma	target WDT		DISABLED			-- no watchdog
pragma	target BROWNOUT	DISABLED			-- no brownout
pragma	target MCLR		INTERNAL			-- internal MCLR

-- make all pins digital I/O
enable_digital_io()

-- library with delay procedures
include delay

-- configure the library before including it
var bit stepper_cw					= on
const word STEPPER_RPM				= 250
const byte STEPPER_STEPS_1TURN		= 48
-- this two below are optional features, read stepper_unipolar_common for details
const bit STEPPER_FREE = on
const bit STEPPER_SMOOTH = on

-- A note about optional features
-- --
-- The optional features can save you a few bytes depending on the configuration you choose
-- this is very handy when you are scarce of memory (when not?)
-- --
-- This is a resume of my experience in this example to ilustrate the options impact on code size
-- --
-- 		Options			| size bytes
--	-------------------------------
--		none (default)	| 503 bytes
--		stepper free	| 458 bytes
--		stepper smooth	| 627 bytes
--		free + smooth	| 582 bytes
--

-- alias for the lib
alias stepper_coil_a is pin_C0
alias stepper_coil_b is pin_C1
alias stepper_coil_c is pin_C2
alias stepper_coil_d is pin_C3

-- set the pins as outputs
pin_C0_direction = output
pin_C1_direction = output
pin_C2_direction = output
pin_C3_direction = output

-- load & init
include stepper_unipolar_nonblocking
stepper_init()

-- lde declaration
alias LED is pin_C5
pin_C5_direction = output

-- vars
-- how many steps to move in the example
var word how_many_steps = 200
-- how many seconds the led will blink
var byte time = 10

-- small delay to prevent overshoot on false start
delay_1s(1)

-- Description:
-- This example will command the motor to do a 200 steps (how_many_steps var) in forward direction
-- in the background, in the meanwhile the CPU will concentrate in a 10 second flashing led
--
-- Then when the led finish his blink it will command the motor to make another 200 steps
-- in the reverse direction but in wave mode, and will flash the led for another 10 sec
--
-- then at the end of flashing the motor will do a 200 steps in half step mode in reverse direction
-- and will flash the led for another 10 sec
--
-- At the end of the 10 second flashing the entire cycle will repeat.
--
-- NOTE:
-- If you don't see a pause in the motor before reversing, then your motor is taking to long
-- to do the how_many_steps (more then 10 seconds)
--
-- In this case you must INCREASE the RPM of the motor or LOWER the value of how_many_steps var
-- until you see a pause before the motor take the reverse direction movement, also you can
-- increase the time of the time of flshing

procedure wait(byte in sec) is
   pragma inline
   -- make a led blick tiwce a second for sec seconds
   for sec loop
      LED = on
      delay_1ms(500)
      LED = off
      delay_1ms(500)
   end loop
end procedure

-- main loop
forever loop
   -- set mode to normal (2-phase)
   stepper_wave = off
   stepper_half = off
   -- forward direction
   stepper_cw = on
   -- set how many steps to move
   stepper_steps = how_many_steps
   -- GO !
   stepper_go = true
   --
   -- blink a led for x second
   wait(time)
   --
   -- set mode to wave
   stepper_wave = on
   stepper_half = off
   -- forward direction
   stepper_cw = on
   -- set how many steps to move
   stepper_steps = how_many_steps
   -- GO !
   stepper_go = true
   --
   -- blink a led for x second
   wait(time)
   --
   -- set mode to normal (2-phase)
   stepper_wave = off
   stepper_half = on
   -- forward direction
   stepper_cw = off
   -- set how many steps to move
   stepper_steps = word(how_many_steps * 4)
   -- GO !
   stepper_go = true
   --
   -- blink a led for x second
   wait(time)
end loop

Generated by JALlib CHM Help System | Source: stepper_unipolar_blocking.jal


stepper_init - JALlib Procedures Help

stepper_init JALLIB PROCEDURE

Signature

procedure stepper_init() is

Description

init procedure for the non blocking version

Include

To use this procedure, include the library:

include stepper_unipolar_nonblocking

Parameters

None

Return Value

None

Example

From sample file: 16f630_stepper_unipolar_nonblocking.jal

-- --------------------------------------------------------------------------------------------
-- Title: Example of the Unipolar Stepper Motor with non blocking delays lib with the pic16f630
-- Author: Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved.
-- Compiler: >=2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple unipolar stepper motor example lib for Microchip pic16f630,
-- using internal HS 4.0 Mhz XTAL, and internal MCLR, with non blocking delays
-- --
-- Non Blocking delays means that the motor run indepndently of the main program
-- or kind of, it uses the TMR0 feature and interrupts to move the motor.
-- --
-- You must provide a unipolar stepper motor in the pins showed below, and it must
-- be conected to a coil driver like a mosfet*4 or or a darlingtown motor driver
-- --
-- I used a ULN2003 to do the testing job...
-- --
-- You MUST know at least the basic principle of unipolar stepper motors, and
-- know what coil/wire is each one (Common, A, B, C, D), or a method to identify it.
-- See stepper_unipolar_common for more details
--
-- Sources:
-- To many to count, kind of http://www.google.com/?hl=en&q=stepper+motor+tutorial and pick the best?
-- PLEASE read the stepper_unipolar_common lib and the stepper_unipolar_blockin lib for details
--
-- Notes:
-- * This file is maintained by hand!!!
-- --
-- device map
--                 +5 V > VCC [1  U  14] GND < GND
--                         A5 [2     13] A0
--                         A4 [3     12] A1
--                         A3 [4     11] A2
--                   LED < C5 [5     10] C0 > A Coil driver
--                         C4 [6      9] C1 > B Coil driver
--        D Coil Driver <  C3 [7      8] C2 > C Coil driver
-- ------------------------------------------------------
--
include 16f630								-- target PIC device
--
pragma	target clock	4_000_000			-- 4 Mhz is the work freq
pragma	target OSC		INTOSC_NOCLKOUT		-- The PIC uses it's own internal 4Mhz CLOCK
pragma	target WDT		DISABLED			-- no watchdog
pragma	target BROWNOUT	DISABLED			-- no brownout
pragma	target MCLR		INTERNAL			-- internal MCLR

-- make all pins digital I/O
enable_digital_io()

-- library with delay procedures
include delay

-- configure the library before including it
var bit stepper_cw					= on
const word STEPPER_RPM				= 250
const byte STEPPER_STEPS_1TURN		= 48
-- this two below are optional features, read stepper_unipolar_common for details
const bit STEPPER_FREE = on
const bit STEPPER_SMOOTH = on

-- A note about optional features
-- --
-- The optional features can save you a few bytes depending on the configuration you choose
-- this is very handy when you are scarce of memory (when not?)
-- --
-- This is a resume of my experience in this example to ilustrate the options impact on code size
-- --
-- 		Options			| size bytes
--	-------------------------------
--		none (default)	| 503 bytes
--		stepper free	| 458 bytes
--		stepper smooth	| 627 bytes
--		free + smooth	| 582 bytes
--

-- alias for the lib
alias stepper_coil_a is pin_C0
alias stepper_coil_b is pin_C1
alias stepper_coil_c is pin_C2
alias stepper_coil_d is pin_C3

-- set the pins as outputs
pin_C0_direction = output
pin_C1_direction = output
pin_C2_direction = output
pin_C3_direction = output

-- load & init
include stepper_unipolar_nonblocking
stepper_init()

-- lde declaration
alias LED is pin_C5
pin_C5_direction = output

-- vars
-- how many steps to move in the example
var word how_many_steps = 200
-- how many seconds the led will blink
var byte time = 10

-- small delay to prevent overshoot on false start
delay_1s(1)

-- Description:
-- This example will command the motor to do a 200 steps (how_many_steps var) in forward direction
-- in the background, in the meanwhile the CPU will concentrate in a 10 second flashing led
--
-- Then when the led finish his blink it will command the motor to make another 200 steps
-- in the reverse direction but in wave mode, and will flash the led for another 10 sec
--
-- then at the end of flashing the motor will do a 200 steps in half step mode in reverse direction
-- and will flash the led for another 10 sec
--
-- At the end of the 10 second flashing the entire cycle will repeat.
--
-- NOTE:
-- If you don't see a pause in the motor before reversing, then your motor is taking to long
-- to do the how_many_steps (more then 10 seconds)
--
-- In this case you must INCREASE the RPM of the motor or LOWER the value of how_many_steps var
-- until you see a pause before the motor take the reverse direction movement, also you can
-- increase the time of the time of flshing

procedure wait(byte in sec) is
   pragma inline
   -- make a led blick tiwce a second for sec seconds
   for sec loop
      LED = on
      delay_1ms(500)
      LED = off
      delay_1ms(500)
   end loop
end procedure

-- main loop
forever loop
   -- set mode to normal (2-phase)
   stepper_wave = off
   stepper_half = off
   -- forward direction
   stepper_cw = on
   -- set how many steps to move
   stepper_steps = how_many_steps
   -- GO !
   stepper_go = true
   --
   -- blink a led for x second
   wait(time)
   --
   -- set mode to wave
   stepper_wave = on
   stepper_half = off
   -- forward direction
   stepper_cw = on
   -- set how many steps to move
   stepper_steps = how_many_steps
   -- GO !
   stepper_go = true
   --
   -- blink a led for x second
   wait(time)
   --
   -- set mode to normal (2-phase)
   stepper_wave = off
   stepper_half = on
   -- forward direction
   stepper_cw = off
   -- set how many steps to move
   stepper_steps = word(how_many_steps * 4)
   -- GO !
   stepper_go = true
   --
   -- blink a led for x second
   wait(time)
end loop

Generated by JALlib CHM Help System | Source: stepper_unipolar_nonblocking.jal


stepper_run - JALlib Procedures Help

stepper_run JALLIB PROCEDURE

Signature

procedure stepper_run(word in rpm) is -- in units of 0.1 RPM

Description

Descr: Set stepper speed to desired RPM
Input: data (word) in 0.1 RPM (50 means 5 RPM)
Notes: - Power to one (or two with halfstep) coils is applied automatically
- Depending on current speed and the specified accelleration and
decelleration settings the stepper speed may change gradually.
- Use stepper_detach() to remove power (automatic with rpm zero)

Include

To use this procedure, include the library:

include steppermotor

Parameters

  • rpm - word in

Return Value

None

Example

From sample file: 16f1765_steppermotor.jal

-- --------------------------------------------------------------
-- Title: Example of using the stepper library
--
-- Author: Rob Hamerling, Copyright (c) 2016, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Simple stepper motor example with 16f1765
--
-- Sources:
--
-- Notes:
--
-- ----------------------------------------------------------

include 16f1765

-- internal oscillator at 8 MHz (with 4xPLL -> 32 MHz)

pragma target clock     32_000_000           -- Fosc

pragma target OSC       INTOSC_NOCLKOUT
pragma target WDT       DISABLED             -- no watchdog
pragma target PWRTE     ENABLED
pragma target MCLR      EXTERNAL
pragma target BROWNOUT  DISABLED
pragma target CLKOUTEN  DISABLED             -- no clock out
pragma target PPS1WAY   DISABLED
pragma target PLLEN     DISABLED             -- PLL software controlled
pragma target LVP       ENABLED              -- allow Low Voltage Programming

OSCCON_IRCF   = 0b1110                       -- 8 MHz
OSCCON_SCS    = 0b00                         -- clock determined by fuses
OSCCON_SPLLEN = TRUE                         -- PLL (8 -> 32 MHz)

if !defined(T3CON_TMR3CS) then               -- omission in device files
   alias T3CON_TMR3CS is T3CON_CS
end if
if !defined(T3CON_T3SYNC) then
   alias T3CON_T3SYNC is T3CON_SYNC
end if
if !defined(T3CON_T3CKPS) then
   alias T3CON_T3CKPS is T3CON_CKPS
end if

if !defined(T1CON_T1CKPS) then               -- omission in device files
   alias T1CON_T1CKPS is T1CON_CKPS
end if

include delay

alias  stepper_led is pin_A0                 -- led
pin_A0_direction    = OUTPUT

alias  stepper_coils  is  portC_low          -- stepper control
portC_low_direction  = ALL_OUTPUT

const word stepper_steps_per_rotation = 48   -- steps per full rotation

include steppermotor                         -- stepper motor library

-- ------- main program --------

forever loop

   stepper_led = ON
   stepper_cw = TRUE                         -- clockwise
   stepper_fullstep = TRUE                   -- full steps
   stepper_accel(100,1500)                   -- acceleration rate 15 RPM/sec
   stepper_decel(100,1500)                   -- deceleration rate 15 RPM/sec
   stepper_led = ON
   stepper_run(600)                          -- 60 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

   stepper_led = ON
   stepper_cw = FALSE                        -- reverse
   stepper_fullstep = FALSE                  -- half steps
   stepper_accel(100,1000)                   -- acceleration rate 10 RPM/sec
   stepper_decel(100,1000)                   -- deceleration rate 10 RPM/sec
   stepper_led = ON
   stepper_run(300)                          -- 30 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

end loop

Generated by JALlib CHM Help System | Source: steppermotor.jal


stepper_stop - JALlib Procedures Help

stepper_stop JALLIB PROCEDURE

Signature

procedure stepper_stop() is

Description

Descr: Stop the stepper gradually according to decelleration ratio
Notes: One coil (maybe 2 with half-step) will remain powered, locks the stepper
Use stepper_detach() to remove power and unlock the stepper

Include

To use this procedure, include the library:

include steppermotor

Parameters

None

Return Value

None

Example

From sample file: 16f1765_steppermotor.jal

-- --------------------------------------------------------------
-- Title: Example of using the stepper library
--
-- Author: Rob Hamerling, Copyright (c) 2016, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Simple stepper motor example with 16f1765
--
-- Sources:
--
-- Notes:
--
-- ----------------------------------------------------------

include 16f1765

-- internal oscillator at 8 MHz (with 4xPLL -> 32 MHz)

pragma target clock     32_000_000           -- Fosc

pragma target OSC       INTOSC_NOCLKOUT
pragma target WDT       DISABLED             -- no watchdog
pragma target PWRTE     ENABLED
pragma target MCLR      EXTERNAL
pragma target BROWNOUT  DISABLED
pragma target CLKOUTEN  DISABLED             -- no clock out
pragma target PPS1WAY   DISABLED
pragma target PLLEN     DISABLED             -- PLL software controlled
pragma target LVP       ENABLED              -- allow Low Voltage Programming

OSCCON_IRCF   = 0b1110                       -- 8 MHz
OSCCON_SCS    = 0b00                         -- clock determined by fuses
OSCCON_SPLLEN = TRUE                         -- PLL (8 -> 32 MHz)

if !defined(T3CON_TMR3CS) then               -- omission in device files
   alias T3CON_TMR3CS is T3CON_CS
end if
if !defined(T3CON_T3SYNC) then
   alias T3CON_T3SYNC is T3CON_SYNC
end if
if !defined(T3CON_T3CKPS) then
   alias T3CON_T3CKPS is T3CON_CKPS
end if

if !defined(T1CON_T1CKPS) then               -- omission in device files
   alias T1CON_T1CKPS is T1CON_CKPS
end if

include delay

alias  stepper_led is pin_A0                 -- led
pin_A0_direction    = OUTPUT

alias  stepper_coils  is  portC_low          -- stepper control
portC_low_direction  = ALL_OUTPUT

const word stepper_steps_per_rotation = 48   -- steps per full rotation

include steppermotor                         -- stepper motor library

-- ------- main program --------

forever loop

   stepper_led = ON
   stepper_cw = TRUE                         -- clockwise
   stepper_fullstep = TRUE                   -- full steps
   stepper_accel(100,1500)                   -- acceleration rate 15 RPM/sec
   stepper_decel(100,1500)                   -- deceleration rate 15 RPM/sec
   stepper_led = ON
   stepper_run(600)                          -- 60 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

   stepper_led = ON
   stepper_cw = FALSE                        -- reverse
   stepper_fullstep = FALSE                  -- half steps
   stepper_accel(100,1000)                   -- acceleration rate 10 RPM/sec
   stepper_decel(100,1000)                   -- deceleration rate 10 RPM/sec
   stepper_led = ON
   stepper_run(300)                          -- 30 RPM
   delay_1s(6)

   stepper_led = OFF
   stepper_stop()                            -- decellerate to 0 RPM
   while (stepper_actual_rpm() != 0) loop
      -- nop
   end loop

end loop

Generated by JALlib CHM Help System | Source: steppermotor.jal


stepper_unipolar_blocking.jal - JALLIB Library Documentation

stepper_unipolar_blocking.jal JALLIB LIBRARY

Title

Library to manage unipolar stepper motors with blocking delays

Author

Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved., Adapted-by: original design for jallib

Compiler

>=2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library implement the drive procedures for UNIPOLAR stepper motors
using blocking delays.
--
See stepper_unipolar_common for modes explanations and optional features

Notes

* You have to know & declare the sweet spot frequency/RPM of your motor before including the lib
as always you can try & error until you find it.
* Release date: 8 Nov 2014
Usage:
--
You need to define some vars/constants/alias BEFORE include the lib:
--
Declare you desired RPM of operation, but this is more complex because the RPM depends
on how many steps the motor needs to make a 360 degree turn, so we need to know that too
const word STEPPER_RPM = 60
const byte STEPPER_STEPS_1TURN = 48
--
The limits on the RPM are from 1 RPM to about 300-600 RPM depending on the steps per full turn
--
WARNING !!!! The STEPPER_RPM * STEPPER_STEPS_1TURN value MUST NEVER be > 65535
or you will get unexpected results.
--
Take notice: the higher the RPM the inaccurate the results on the timing, you have been warned !
--
The direction of movement is controlled by this var (by default CW)
var bit stepper_cw = on
--
I choose this convention: ON is forward (CW), OFF is reverse (CCW)
You can olso invert the direction by hardware, so make up your logic to match this...
--
Then you must declare the pins and let them be outputs, you need 4 of them, called A, B, C, D
alias stepper_coil_a is pin_a0
alias stepper_coil_b is pin_a1
alias stepper_coil_c is pin_a2
alias stepper_coil_d is pin_a3
--
Declare them as outputs
pin_A0_direction = output
pin_A1_direction = output
pin_A2_direction = output
pin_A3_direction = output
--
You can now define the mode (only if different from normal which is the default)
stepper_half = on
stepper_wave = off
--
Define the options if needed (see stepper_unipolar_common for details)
const bit STEPPER_FREE = on
const bit STEPPER_SMOOTH = on
--
You can load now the lib & initialize it
include stepper_unipolar_blocking
stepper_init()
--
See the examples for more details

This is the blocking version so we instruct the common lib about

Sources

I used a tutorial (in spanish) here http://www.todorobot.com.ar/informacion/tutorial%20stepper/
This is a very good source also http://www.cs.uiowa.edu/~jones/step/ thanks vasi vasi
A lib on jallib (in unreleased state) at the end of the development by Richard Zengerink dating
back to 2010 give me some new ideas, thanks to all who put his knowledge in the public domain.

Constants and Variables

STEPPER_BLOCKIGN - const bit = on

Routines

  • stepper_go - Procedure
  • stepper_init - Procedure


stepper_unipolar_common.jal - JALLIB Library Documentation

stepper_unipolar_common.jal JALLIB LIBRARY

Title

Library to manage unipolar stepper motors, common lib

Author

Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved.

Compiler

>=2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library files implement the drive procedures for UNIPOLAR stepper motors
This file is the common vars/constants/procs to all stepper unipolar libs
--
This lib supports 3 modes for the operation of stepper motors:
--
This is a schematic representation of the wire naming of this lib
A(B) Common C(D) < Coils ends
| | |
mmmmmmmmmmmmmmmmmmmmmm < coils
--
The first letter is for one coil, the second in parenthesis is the second coil designation
--
- 2-PHASE MODE (two coils at any time) this will be called NORMAL (and default) mode...
Maximum torque of 1.41 times of just one coil (WAVE drive),
then it use double the current of one coil, and the step is the normal
ratio of the one on the datasheet, it uses 4 states, se the table below
| A | B | C | D | decimal
1 | 1 | 1 | 0 | 0 | 12
2 | 0 | 1 | 1 | 0 | 6
3 | 0 | 0 | 1 | 1 | 3
4 | 1 | 0 | 0 | 1 | 9
--
in the config this will be
var bit stepper_half = off ; set half mode to off
var bit stepper_wave = off ; set wave mode to off
--
- WAVE DRIVE mode (one coil any time)
Normal torque, some motors like this mode more than normal mode,
current is the normal rating for one coil, the step is also the normal
specified value from the datasheet, it also uses 4 states, see table
| A | B | C | D | decimal
1 | 1 | 0 | 0 | 0 | 8
2 | 0 | 1 | 0 | 0 | 4
3 | 0 | 0 | 1 | 0 | 2
4 | 0 | 0 | 0 | 1 | 1
--
in the config this will be
var bit stepper_half = off ; set half mode to off
var bit stepper_wave = on ; set wave mode to ON
--
- HALF STEP mode (two/one coils at intervals)
Torque is a mix of full and normal torque at intervals, as also the current;
because it use the two sequences stated before to make half steps, then
it uses 8 states beside the normal 4 states, see table
| A | B | C | D | decimal
1 | 1 | 0 | 0 | 0 | 8
2 | 1 | 1 | 0 | 0 | 12
3 | 0 | 1 | 0 | 0 | 4
4 | 0 | 1 | 1 | 0 | 6
5 | 0 | 0 | 1 | 0 | 2
6 | 0 | 0 | 1 | 1 | 3
7 | 0 | 0 | 0 | 1 | 1
8 | 1 | 0 | 0 | 1 | 9
--
in the config this will be
var bit stepper_half = off ; set half mode to off
the value of stepper_wave is ignored in this mode.
--
This libs have 2 Options that are activated just by defining the appropriate constant BEFORE
calling any of the two libraries (with blocking delays or not) This options are not compiled
if not defined, so small code is generated on demand ;-)
--
* Freeing the coils at the end of the movement, you must provide a mechanical lock
for the gears to remains in place, or ignore it if this is not important in your
application also the motor drain no power when resting, so green power!!! ;-)
const bit STEPPER_FREE = on
--
* Smoothing the start and stop on loads with inertia, the lib will use a trick of slow
the start & stop pulses (hence INCREASE the DUTY CYCLE) using the 0.2% of the speed as
the amount of pulses; this value (0.1%) is experimental an my guess, any improvements
on this procedure (theory or code) is welcomed to my email (see top of file for email)
const bit STEPPER_SMOOTH = on

Sources

I used a tutorial (in spanish) here http://www.todorobot.com.ar/informacion/tutorial%20stepper/
This is a very good source also http://www.cs.uiowa.edu/~jones/step/ thanks vasi vasi
A lib on jallib (in unreleased state) at the end of the development by Richard Zengerink dating
back to 2010 give me some new ideas, thanks to all who put his knowledge in the public domain.

include needed libs

Constants and Variables

STEPPER_RPM - const word = 60
STEPPER_STEPS_1TURN - const word = 48
stepper_cw - var bit = on
stepper_delay - var word = 0
stepper_half - var bit = off -- by default half step if off
by default half step if off
stepper_wave - var bit = off -- by default is normal mode
by default is normal mode
smooth_pulses - var word = 0

Routines

  • stepper_off - Procedure
  • stepper_step - Procedure


stepper_unipolar_nonblocking.jal - JALLIB Library Documentation

stepper_unipolar_nonblocking.jal JALLIB LIBRARY

Title

Library to manage unipolar stepper motors with non blocking delays

Author

Pavel Milanes Costa (CO7WT) - pavelmc@gmail.com, copyright (c) 2014, all rights reserved., Adapted-by: original design for jallib

Compiler

>=2.4q3

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library implement the drive procedures for UNIPOLAR stepper motors
See stepper_unipolar_common.jal for modes explanations

Notes

* You must define the kind of mode you will use AFTER include the lib, if not it will use normal.
* You have to know & declare the sweet spot frecuency/RPM of your motor, but... you can guess.
* You can change the mode on the fly, but need to send a stepper_init() each time after that.
* Creation date/time: 4 Nov 2014 04:28:50.UTC
* This file is maintained by hand!!!
Usage:
* You have to know & declare the sweet spot frequency/RPM of your motor before including the lib
as always you can try & error until you find it.
* Release date: 8 Nov 2014
Usage:
--
You need to define some vars/constants/alias BEFORE include the lib:
--
Declare you desired RPM of operation, but this is more complex because the RPM depends
on how many steps the motor needs to make a 360 degree turn, so we need to know that too
const word STEPPER_RPM = 60
const byte STEPPER_STEPS_1TURN = 48
--
The limits on the RPM are from 1 RPM to about 300-600 RPM depending on the steps per full turn
--
WARNING !!!! The STEPPER_RPM * STEPPER_STEPS_1TURN value MUST NEVER be > 65535
or you will get unexpected results.
--
Take notice: the higher the RPM the inaccurate the results on the timing, you have been warned !
--
The direction of movement is controlled by this var (by default CW)
var bit stepper_cw = on
--
I choose this convention: ON is forward (CW), OFF is reverse (CCW)
You can olso invert the direction by hardware, so make up your logic to match this...
--
Then you must declare the pins and let them be outputs, you need 4 of them, called A, B, C, D
alias stepper_coil_a is pin_a0
alias stepper_coil_b is pin_a1
alias stepper_coil_c is pin_a2
alias stepper_coil_d is pin_a3
--
Declare them as outputs
pin_A0_direction = output
pin_A1_direction = output
pin_A2_direction = output
pin_A3_direction = output
--
You can now define the mode (only if different from normal which is the default)
stepper_half = on
stepper_wave = off
--
Define the options if needed (see stepper_unipolar_common for details)
const bit STEPPER_FREE = on
const bit STEPPER_SMOOTH = on
--
You can load now the lib & initialize it
include stepper_unipolar_blocking
stepper_init()
--
See the examples for more details

This is the non blocking version so we instruct the common lib about

Sources

I used this tutorial in spanish here http://www.todorobot.com.ar/informacion/tutorial%20stepper/
This is a good source also http://www.cs.uiowa.edu/~jones/step/ thanks vasi vasi for the link.

Constants and Variables

STEPPER_BLOCKIGN - const bit = off
stepper_go - var bit = off
stepper_steps - var word = 0
real_delay - var word = stepper_delay

Routines

  • _int_setup - Procedure
  • isr_proc - Procedure
  • stepper_init - Procedure


steppermotor.jal - JALLIB Library Documentation

steppermotor.jal JALLIB LIBRARY

Title

Single stepper motor library (unipolar or bipolar)

Author

Richard Zengerink, Copyright (c) 2009..2010, all rights reserved., Adapted-by: Rob Hamerling (2016)

Compiler

2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for a single stepper motor.
Includes configurable startup- en slowdown-curves
and optionally user-defined control patterns.
Designed and tested with a unipolar motor,
but can be used with a bipolar motor as well.
Supports inverting and non-inverting buffer-ICs
.
Required declarations before including the library:
This library uses 4 control pins to control a stepper motor.
When all pins are in the same nibble (most efficient) declare an alias
for this nibble, for example when pins pin_B0 through pin_B3 are used:
alias stepper_coils is portB_low
and set all the pins if this nibble to output:
portB_low_direction = ALL_OUTPUT
Alternatively with individual pins (not necessarily on the same nibble)
alias stepper_coil1a is pin_B0
alias stepper_coil2a is pin_B1
alias stepper_coil1b is pin_C0
alias stepper_coil2b is pin_C1
and set these pins to output:
pin_B0 = OUTPUT
pin_B1 = OUTPUT
pin_C0 = OUTPUT
pin_C1 = OUTPUT
The wiring of the 4 pins to the coils must of course match
the bit patterns in the arrays below!
.
A constant array of bit patterns is required to
specify the signal state for each half-step:
const byte STEPPER_ARRAY[8] =
{
0b_0001, -- coil 1a
0b_0011, -- coil 1a + 2a
0b_0010, -- coil 2a
0b_0110, -- coil 2a + 1b
0b_0100, -- coil 1b
0b_1100, -- coil 1b + 2b
0b_1000, -- coil 2b
0b_1001 -- coil 2b + 1a
}
These bit patterns are examples for a unipolar stepper motor and
are the defaults when the array is absent in the user program.
The entries specify the bit pattern for every half step in
clock-wise rotation.
In full-step mode only the even entries of the array are used.
With bipolar stepper motors or with special buffer-ICs
the appropriate patterns need be defined by the user program.
In any case the bit pattern should match the actual wiring and
your definition of clockwise!
.
Specify a bit constant to indicate when you use an inverting
buffer-IC to control the stepper motor:
const bit STEPPER_INVERTING_BUFFER = TRUE
When not specified the default behaviour is non-inverting.
.
A word constant must be declared which specifies the number of steps
for a complete rotation of the stepper motor axis in full-step mode,
for example:
const word STEPPER_STEPS_PER_ROTATION = 200
.
A bit variable 'stepper_cw' must be declared to specify the direction of
rotation. Value TRUE means 'clockwise' and FALSE 'counter-clockwise'.
var bit stepper_cw = TRUE
Make sure your wiring matches this setting and the way the stepper moves.
The value may be changed dynamically by the user program.
.
A bit variable 'stepper_fullstep' must be declared to indicate
that the stepper must run at full-steps (TRUE) or half-steps (FALSE).
var bit stepper_fullstep = TRUE
The value may be changed dynamically by the user program.
.
This library was initially designed for PICs with 16-bits wide Timer0.
This excluded the use of midrange PICs, which have only 8-bits Timer0.
A 16-bits timer is required to support a wide enough speedrange
of stepper motors. When using a PIC without a 16-bits wide Timer0
this revised version of the library automatically selects Timer3 or
the PWM3 modules when present.
.
Available public procedures:
stepper_run() -- set motor speed (accellerate/decellerate smoothly)
stepper_stop() -- stop motor (decellerate smoothly)
stepper_hold() -- stop motor immediately and lock it (keep powered)
stepper_accel() -- set acceleration ratio (smooth accelleration)
stepper_decel() -- set decellaration ratio (smooth decelleration)
stepper_detach() -- stop motor immediately and release it (power off)
stepper_attach() -- lock motor in position (power on, no stepping)
stepper_actual_rpm() -- return actual rpm

Constants and Variables

STEPPER_TIMER1_RELOAD - const word = 65535 - word(target_clock / 4 / STEPPER_TIMER1_PRESCALE / 100)
stepper_cw - var bit = TRUE -- TRUE is clockwise, FALSE = counter clockwise
TRUE is clockwise, FALSE = counter clockwise
stepper_fullstep - var bit = TRUE -- TRUE is full step, FALSE half step
TRUE is full step, FALSE half step
stepper_accel_active - var bit = FALSE -- is set during accelleration
is set during accelleration
stepper_decel_active - var bit = FALSE -- is set during decelleration
is set during decelleration
stepper_running - var bit = FALSE -- is set during run and reset after stop
is set during run and reset after stop
stepper_to_stop - var bit = FALSE -- is set during stop slope and reset after stop
is set during stop slope and reset after stop
stepper_slope_speedset - var bit = FALSE -- TRUE while accellerating/decellerating
TRUE while accellerating/decellerating
stepper_accel_ratio - var word = 0 -- accelleration ratio in rpm/sec
accelleration ratio in rpm/sec
stepper_decel_ratio - var word = 0 -- decelleration ratio in rpm/sec
decelleration ratio in rpm/sec
stepper_steptimer_interval - var word = 0 -- holds actual interval for stepper timer
holds actual interval for stepper timer
stepper_set_speed - var word = 0 -- desired speed in 1/10 rpm
desired speed in 1/10 rpm
stepper_actual_speed - var word = 0 -- actual speed in 1/10 rpm
actual speed in 1/10 rpm
stepper_step_index - var byte = 0 -- index in step pattern array
index in step pattern array
STEPPER_STEPS_PER_ROTATION - const word = 200
STEPPER_INVERTING_BUFFER - const bit = FALSE

Routines

  • stepper_accel - Procedure
  • stepper_actual_rpm - Function returns sword
  • stepper_attach - Procedure
  • stepper_control - Procedure
  • stepper_decel - Procedure
  • stepper_detach - Procedure
  • stepper_hold - Procedure
  • stepper_run - Procedure
  • stepper_slope_timer_isr - Procedure
  • stepper_stepticks - Function returns word
  • stepper_steptimer_isr - Procedure
  • stepper_stop - Procedure
  • stepper_timer1_off - Procedure
  • stepper_timer1_on - Procedure
  • stepper_timer_load - Procedure


stopwatch2.jal - JALLIB Library Documentation

stopwatch2.jal JALLIB LIBRARY

Title

Stopwatch library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2023, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Creates a stopwatch for timing events

Notes

You do not need to define any constants in your program. Stopwatch will
choose these default values for you.
const STOPWATCH2_VAR_SIZE = 4
const STOPWATCH2_MIN_VALUE = STOPWATCH_NS
const STOPWATCH2_USE_TIMER = 1
You will probobly not need to do error checking by reading
stopwatch2_time_overflow with STOPWATCH2_VAR_SIZE = 4
max time measurement is STOPWATCH2_MIN_VALUE 0xFFFF or 0xFFFFFFFF
depending on STOPWATCH2_VAR_SIZE, or (1/0SC*4*0xFF_FF_FF_FF_FF_FF)
example: with STOPWATCH_NS and STOPWATCH2_VAR_SIZE = 2, the max time to
measure is 65535ns
I have not tested instruction measurement of greater then 0xFFFF

set some default values if no constants are defined:
set stopwatch2 variable size, (2 = word) or (4 = dword)

Routines

  • stopwatch2_continue - Procedure
  • stopwatch2_cycle_overflow'get - Function returns bit
  • stopwatch2_init - Procedure
  • stopwatch2_isr - Procedure
  • stopwatch2_start - Procedure
  • stopwatch2_stop - Procedure
  • stopwatch2_time_overflow'get - Function returns bit


stopwatch2_init - JALlib Procedures Help

stopwatch2_init JALLIB PROCEDURE

Signature

procedure stopwatch2_init() is

Description

initialize the stopwatch2

Include

To use this procedure, include the library:

include stopwatch2

Parameters

None

Return Value

None

Example

From sample file: 16f15325_stopwatch2.jal

-- -----------------------------------------------------------------------------
-- Title: Test program for Stopwatch2.
-- Author: Rob Jansen, Copyright (c) 2023..2023 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This example shows basic usage stopwatch2 library which can
--              be used to time events.
--
-- Sources:     This program is based on the stopwatch sample program created by
--              Matt Schinkel. It was created for testing - compiling - the update
--              of the stopwatch library for newer PIC types like the 16F15325.
--
-- Notes:       This sample program is created manually.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division

-- Enable weak pull up for all ports
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()   -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- Declaration of the USART1 pins
alias pin_RX_direction  is pin_C4_direction
alias pin_TX_direction  is pin_C5_direction

-- Re-assign the pins. Note: This must always be done to let it work
-- even for the default assignment.
include pps
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
pps_control_lock(TRUE)

-- setup uart for communication
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH2_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH2_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH2_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch2 -- include the library
--
stopwatch2_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch2_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch2_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch2_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch2 time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch2_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch2 instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2)

-- print the time unit of measurement
if STOPWATCH2_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

-- Give the serial port some time to send the last characters.
_usec_delay(100_000)

Generated by JALlib CHM Help System | Source: stopwatch2.jal


stopwatch2_start - JALlib Procedures Help

stopwatch2_start JALLIB PROCEDURE

Signature

procedure stopwatch2_start() is

Description

start the stopwatch2 at time = 0

Include

To use this procedure, include the library:

include stopwatch2

Parameters

None

Return Value

None

Example

From sample file: 16f15325_stopwatch2.jal

-- -----------------------------------------------------------------------------
-- Title: Test program for Stopwatch2.
-- Author: Rob Jansen, Copyright (c) 2023..2023 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This example shows basic usage stopwatch2 library which can
--              be used to time events.
--
-- Sources:     This program is based on the stopwatch sample program created by
--              Matt Schinkel. It was created for testing - compiling - the update
--              of the stopwatch library for newer PIC types like the 16F15325.
--
-- Notes:       This sample program is created manually.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division

-- Enable weak pull up for all ports
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()   -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- Declaration of the USART1 pins
alias pin_RX_direction  is pin_C4_direction
alias pin_TX_direction  is pin_C5_direction

-- Re-assign the pins. Note: This must always be done to let it work
-- even for the default assignment.
include pps
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
pps_control_lock(TRUE)

-- setup uart for communication
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH2_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH2_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH2_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch2 -- include the library
--
stopwatch2_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch2_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch2_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch2_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch2 time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch2_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch2 instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2)

-- print the time unit of measurement
if STOPWATCH2_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

-- Give the serial port some time to send the last characters.
_usec_delay(100_000)

Generated by JALlib CHM Help System | Source: stopwatch2.jal


stopwatch2_stop - JALlib Procedures Help

stopwatch2_stop JALLIB PROCEDURE

Signature

procedure stopwatch2_stop() is

Description

stop the stopwatch2

Include

To use this procedure, include the library:

include stopwatch2

Parameters

None

Return Value

None

Example

From sample file: 16f15325_stopwatch2.jal

-- -----------------------------------------------------------------------------
-- Title: Test program for Stopwatch2.
-- Author: Rob Jansen, Copyright (c) 2023..2023 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This example shows basic usage stopwatch2 library which can
--              be used to time events.
--
-- Sources:     This program is based on the stopwatch sample program created by
--              Matt Schinkel. It was created for testing - compiling - the update
--              of the stopwatch library for newer PIC types like the 16F15325.
--
-- Notes:       This sample program is created manually.
--
include 16f15325

-- ------------------------------- Pragmas -------------------------------------

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division

-- Enable weak pull up for all ports
WPUA = 0b0001_1111
WPUC = 0b0001_1111

enable_digital_io()   -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- Declaration of the USART1 pins
alias pin_RX_direction  is pin_C4_direction
alias pin_TX_direction  is pin_C5_direction

-- Re-assign the pins. Note: This must always be done to let it work
-- even for the default assignment.
include pps
pps_control_lock(FALSE)
RC5PPS   = PPS_TX1       -- TX1 re-assigned to C5  (default)
RX1DTPPS = PPS_RC4       -- C4  re-assigned to RX1 (default)
pps_control_lock(TRUE)

-- setup uart for communication
const serial_hw_baudrate = 115_200
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH2_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH2_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH2_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch2 -- include the library
--
stopwatch2_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch2_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch2_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch2_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch2 time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch2_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch2 instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch2)

-- print the time unit of measurement
if STOPWATCH2_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH2_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

-- Give the serial port some time to send the last characters.
_usec_delay(100_000)

Generated by JALlib CHM Help System | Source: stopwatch2.jal


stopwatch.jal - JALLIB Library Documentation

stopwatch.jal JALLIB LIBRARY

Title

Stopwatch library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009..2023, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r8

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Creates a stopwatch for timing events

Notes

You do not need to define any constants in your program. Stopwatch will
choose these default values for you.
const STOPWATCH_VAR_SIZE = 4
const STOPWATCH_MIN_VALUE = STOPWATCH_NS
const STOPWATCH_USE_TIMER = 1
You will probobly not need to do error checking by reading
stopwatch_time_overflow with STOPWATCH_VAR_SIZE = 4
max time measurement is STOPWATCH_MIN_VALUE 0xFFFF or 0xFFFFFFFF
depending on STOPWATCH_VAR_SIZE, or (1/0SC*4*0xFF_FF_FF_FF_FF_FF)
example: with STOPWATCH_NS and STOPWATCH_VAR_SIZE = 2, the max time to
measure is 65535ns
I have not tested instruction measurement of greater then 0xFFFF

set some default values if no constants are defined:
set stopwatch variable size, (2 = word) or (4 = dword)

Routines

  • stopwatch_continue - Procedure
  • stopwatch_cycle_overflow'get - Function returns bit
  • stopwatch_init - Procedure
  • stopwatch_isr - Procedure
  • stopwatch_start - Procedure
  • stopwatch_stop - Procedure
  • stopwatch_time_overflow'get - Function returns bit


stopwatch_init - JALlib Procedures Help

stopwatch_init JALLIB PROCEDURE

Signature

procedure stopwatch_init() is

Description

initialize the stopwatch

Include

To use this procedure, include the library:

include stopwatch

Parameters

None

Return Value

None

Example

From sample file: 18f452_stopwatch.jal

-- Title: Test program for Stopwatch
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example shows basic usage stopwatch library which can
--              be used to time events
--
-- Sources:
--
-- This file has been generated by jallib.py from:
--    * board: board_18f452_dwarf.jal
--    * test : test_stopwatch.jal
--

;@jallib section chipdef
-- chip setup
include 18f452

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled                     -- allow LVP
pragma target   WDT CONTROL                     -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog

;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch -- include the library
--
stopwatch_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch)

-- print the time unit of measurement
if STOPWATCH_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

Generated by JALlib CHM Help System | Source: stopwatch.jal


stopwatch_start - JALlib Procedures Help

stopwatch_start JALLIB PROCEDURE

Signature

procedure stopwatch_start() is

Description

start the stopwatch at time = 0

Include

To use this procedure, include the library:

include stopwatch

Parameters

None

Return Value

None

Example

From sample file: 18f452_stopwatch.jal

-- Title: Test program for Stopwatch
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example shows basic usage stopwatch library which can
--              be used to time events
--
-- Sources:
--
-- This file has been generated by jallib.py from:
--    * board: board_18f452_dwarf.jal
--    * test : test_stopwatch.jal
--

;@jallib section chipdef
-- chip setup
include 18f452

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled                     -- allow LVP
pragma target   WDT CONTROL                     -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog

;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch -- include the library
--
stopwatch_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch)

-- print the time unit of measurement
if STOPWATCH_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

Generated by JALlib CHM Help System | Source: stopwatch.jal


stopwatch_stop - JALlib Procedures Help

stopwatch_stop JALLIB PROCEDURE

Signature

procedure stopwatch_stop() is

Description

stop the stopwatch

Include

To use this procedure, include the library:

include stopwatch

Parameters

None

Return Value

None

Example

From sample file: 18f452_stopwatch.jal

-- Title: Test program for Stopwatch
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example shows basic usage stopwatch library which can
--              be used to time events
--
-- Sources:
--
-- This file has been generated by jallib.py from:
--    * board: board_18f452_dwarf.jal
--    * test : test_stopwatch.jal
--

;@jallib section chipdef
-- chip setup
include 18f452

pragma target clock 20_000_000                  -- xtal frequency
pragma target OSC        hs
pragma target   LVP enabled                     -- allow LVP
pragma target   WDT CONTROL                     -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog

;@jallib section serial
const serial_hw_baudrate = 115_200

enable_digital_io() -- disable all analog pins if any
_usec_delay (100_000) -- wait for power to stablilize

include delay

-- setup uart for communication
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

include print

-- set stopwatch variable size, (2 = word) or (4 = dword)
const STOPWATCH_VAR_SIZE = 4 -- (4 is default if not defined)
--
-- the lowest time unit to measure
const STOPWATCH_MIN_VALUE = STOPWATCH_NS -- (STOPWATCH_NS is default if not defined)
--
-- choose what timer to use
const STOPWATCH_USE_TIMER = 1 -- (1 is default if not defined)
include stopwatch -- include the library
--
stopwatch_init()

-- main program here

-- print serial start characters
print_crlf(serial_hw_data)
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = " "

stopwatch_start() -- start the stopwatch

-- create some delay to measure
asm nop
;delay_1us() -- some delay
;delay_1ms(1) -- some delay
;delay_1s(1) -- some delay

stopwatch_stop() -- stop the stopwatch

-- print error message if stopwatch time was too long
if stopwatch_time_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error1[] = "Stopwatch time overflow error occurred"
   print_string(serial_hw_data, error1)
end if

-- print error message if stopwatch instruction count ran too long
if stopwatch_cycle_overflow == TRUE then
   print_crlf(serial_hw_data)
   const byte error2[] = "Stopwatch instruction cycle overflow error occurred"
   print_string(serial_hw_data, error2)
end if

-- measure instructions run and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch_cycles)
const byte instructions[] = " instruction(s)"
print_string(serial_hw_data, instructions)

-- measure time taken and print it to serial port
print_crlf(serial_hw_data)
print_dword_dec(serial_hw_data, stopwatch)

-- print the time unit of measurement
if STOPWATCH_MIN_VALUE == STOPWATCH_NS then
   serial_hw_data = "n"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_US then
   serial_hw_data = "u"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_MS then
   serial_hw_data = "m"
   serial_hw_data = "s"
elsif STOPWATCH_MIN_VALUE == STOPWATCH_S then
   serial_hw_data = "s"
end if

-- print serial end characters
print_crlf(serial_hw_data)
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"
serial_hw_data = "!"

Generated by JALlib CHM Help System | Source: stopwatch.jal


storage_drivers.jal - JALLIB Library Documentation

storage_drivers.jal JALLIB LIBRARY

Title

storage device drivers (aliases)

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This lib contains storage device drivers (aliases), so any mass
storage device can be used for libraries such as fat32, usb_msd, etc.

Sources

Alias storage device
hard disk procedures

Routines

  • storage_sector_buffer_high'get - Function returns byte
  • storage_sector_buffer_high'put - Procedure
  • storage_sector_buffer_low'get - Function returns byte
  • storage_sector_buffer_low'put - Procedure


string_compare - JALlib Procedures Help

string_compare JALLIB FUNCTION

Signature

function string_compare(byte in string1[], byte in string2[]) return bit is

Description

compare two strings to see if they are the same. not case dependant.
strings can optionally be terminated with a null character.
(null character = 0).

Include

To use this procedure, include the library:

include strings

Parameters

  • string1[] - byte in
  • string2[] - byte in

Return Value

bit - Function return value

Example

From sample file: 18f4620_mp3_decoder_vs1053b_pata_hard_disk.jal

-- Title: MP3 decoder vs1053b sample
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example usage of the vs1053 mp3 decoder. plays .mp3 files from
--              a fat32 formatted sd card or hard disk. Full control of play
--              speed, volume, right/left speaker, bass, treble, mute.
--              Also plays Ogg Vorbis/AAC/WMA/MIDI
--
-- Notes:
-- vs1053 uses SPI mode 0,0
-- must use 12.288mhz crystal for vs1053b
--
-- Sources:
-- VLSI Solutions Datasheet - www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include strings

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- setup vs1053(b)
const byte str3[] = "INITIALIZING VS1053B"
print_string(serial_hw_data, str3)
--
alias vs_command_chip_select              is pin_e1                     -- command chip select pin
alias vs_command_chip_select_direction    is pin_e1_direction
alias vs_data_chip_select                 is pin_e2                     -- data chip select pin
alias vs_data_chip_select_direction       is pin_e2_direction
alias vs_dreq                             is pin_c0                     -- data request pin
alias vs_dreq_direction                   is pin_c0
--
vs_command_chip_select_direction = output
vs_data_chip_select_direction = output
vs_dreq_direction = input
--
vs_command_chip_select = high -- disable command chip select
vs_data_chip_select = high -- disable data chip select
--
-- select weather or not to switch SPI modes before every read/write
-- needed if using more then one component on the SPI bus.
-- enabled when vs_force_spi_mode is defined.
alias vs_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
--
-- 5x pll (interal clock runs at 12.288mhz * 5 = 61.44)
-- note: higher SPI speeds require high PLL
const byte VS_PLL = 5 -- choose 1, 3_5 (3.5), or 5
const byte VS_SPI_COMMAND_SPEED = SPI_RATE_FOSC_64 -- choose speed to send commands
--
include mp3_decoder_vs1053b
vs_init()

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- start of main program
vs_volume = 240 -- set startup volume

-- example of using an output pin
var bit my_pin_name is vs_pin_gpio0
var bit my_pin_name_direction is vs_pin_gpio0_direction
my_pin_name_direction = output
my_pin_name = high

-- some vars
var sword db_level  -- will hold volume db (decibel) level

seperator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

------------------------------------------------------------
-- example user interaction,
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into a mp3 file and play it
------------------------------------------------------------

var byte file_number = 0
var dword count8 = 0

forever loop
   seperator() -- send "-----"

   -- wait for user to send serial data (file selection)
   while !serial_hw_data_available loop
   end loop

   file_number = serial_hw_data

   if !(file_number > fat32_dir_file_count) then -- if the file number exists
      -- display the file_name chosen
      print_word_dec(serial_hw_data,file_number)
      const byte string1[] = {0x2E,0x20,0x20} -- ".  "
      print_string(serial_hw_data,string1)
      fat32_read_file_info(file_number) -- read file's name, location, size, attributes into memory
      fat32_print_file_info(serial_hw_data,FAT32_PRINT_ALL)
      seperator() -- send "-----"
   end if

   -- do something with the chosen file number
   if fat32_cd(file_number) then            -- if change directory is successful
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL)                      -- sends dir listing via serial port

   elsif fat32_file_open(file_number) then  -- if file open is successful
      var dword sector_step = 0
      count8 = 0

      vs_play() -- allow vs1053b to play music

      -- continue till no data is left.
      for (fat32_file_size / 512) + 1 loop
         fat32_read_file_sector_number(sector_step)
         sector_step = sector_step + 1

         -- do something with the data
         if string_compare(fat32_file_extension, "mp3") then

            -- now send it to vs1053b

            -- set to spi mode 00
            spi_master_hw_set_mode_00()

            -- enable vs1053b
            vs_data_chip_select = low

            var word count1                        -- sector data count
            count1 = 0
            for 16 loop                             -- loop till end of sector read

               -- wait till data gets requested
               while vs_dreq == low loop
               end loop

               -- vs1053b can take up to 32 bytes when vs_dreq is low
               for 32 loop
                  spi_master_hw = fat32_sector_buffer[count1]
                  count1 = count1 + 1
               end loop
            end loop
         else
            var word count1 = 0
            for 512 loop
               serial_hw_data = fat32_sector_buffer[count1]
               count1 = count1 + 1
            end loop
         end if

         -- get users input via serial port to control music (volume, play speed, stop, etc.)
         if serial_hw_data_available == TRUE then
            var byte serial_data = serial_hw_data
            if serial_data == 0 then                    -- stop
               fat32_set_idle()          -- set data device to idle state
               vs_stop()                 -- stop the audio
               vs_data_chip_select = low -- disable mp3 decoder
               exit loop
            elsif serial_data == 50 then                -- volume down
               if vs_volume != 0 then
                  vs_volume = vs_volume - 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 51 then                -- volume up
               if vs_volume != 255 then
                  vs_volume = vs_volume + 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 52 then                -- volume down right only
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 53 then                -- volume up right only
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 54 then                -- volume down left only
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 55 then                -- volume up left only
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 56 then                -- move volume right to left
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 57 then                -- move volume left to right
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 58 then                -- slower play speed
               if !(vs_play_speed == 1) then
                  vs_play_speed = vs_play_speed - 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 59 then                -- faster play speed (fast-forward)
               if !(vs_play_speed == 10) then
                  vs_play_speed = vs_play_speed + 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 60 then                -- get file info, so far
               vs_file_info()                           -- only file type " MP3", "MIDI", etc.
               print_string(serial_hw_data,vs_current_file_type) -- send filetype
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_bitrate)       -- send bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_average_bitrate) -- send avgerage bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_samplerate)  -- send samplerate
               print_crlf(serial_hw_data)
            elsif serial_data == 61 then                -- MUTE
               vs_mute = TRUE
               print_byte_dec(serial_hw_data, 1)
            elsif serial_data == 62 then                -- NO MUTE
               vs_mute = FALSE
               print_byte_dec(serial_hw_data, vs_mute)
            elsif serial_data == 63 then                -- bass down
               if vs_bass != 0 then
                  vs_bass = vs_bass - 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 64 then                -- bass up
               if vs_bass != 15 then
                  vs_bass = vs_bass + 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 65 then                -- treble down
               if vs_treble != -8 then
                  vs_treble = vs_treble - 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            elsif serial_data == 66 then                -- treble up
               if vs_treble != 7 then
                  vs_treble = vs_treble + 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            end if

            -- send return char
            serial_hw_data = 13
            serial_hw_data = 10
         end if
         vs_data_chip_select = high -- disable vs1053b
         count8 = count8 + 1

      end loop
      -- close the file
      fat32_file_close()
      seperator()
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   end if
end loop

Generated by JALlib CHM Help System | Source: strings.jal


string_compare_mid - JALlib Procedures Help

string_compare_mid JALLIB FUNCTION

Signature

function string_compare_mid(byte in string1[], byte in start, byte in string2[]) return bit is

Description

compare the middle of string1 with string2
string1 must be >= length of string2

Include

To use this procedure, include the library:

include strings

Parameters

  • string1[] - byte in
  • start - byte in
  • string2[] - byte in

Return Value

bit - Function return value

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: strings.jal


string_to_dword - JALlib Procedures Help

string_to_dword JALLIB FUNCTION

Signature

function string_to_dword(byte in chars[]) return dword is

Description

Convert a string representing a number into the actual number, as dword.
The Number may fill the whole array, or can be terminated by any non-number
character. If the first character is not a number, zero is returned.
If the number is too large, a wrong value is returned without notice.

Include

To use this procedure, include the library:

include strings

Parameters

  • chars[] - byte in

Return Value

None

Example

From sample file: 16f19176_dfplayer.jal

-- -----------------------------------------------------------------------------
-- Title: DFPlayer Mini sample program.
--
-- Author: Rob Jansen, Copyright (c) 2020..2020, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources:
--
-- Description: Extensive sample program that shows all features of the JAL
--              library for the DFPlayer Mini.
--              For a simple demo version see 16f1823_dfplayer.jal
--
-- PIC connections (40 pin DIP):
-- *) TX 1: pin 25 of the USART1 of the PIC to the RX pin of the DFPlayer.
-- *) RX 1: pin 26 of the USART1 of the PIC to the TX pin of the DFPlayer.
-- *) TX 2: pin 22 of the USART2 of the PIC to the pin 11 of the MAX232.
-- *) RX 2: pin 21 of the USART2 of the PIC to the pin 12 of the MAX232.
--

-- ------------------------------- Pragmas -------------------------------------

include 16f19176

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000  -- oscillator frequency
--
pragma target OSC      OFF         -- internal oscillator
pragma target RSTOSC   HFINT32     -- select 32 MHz
pragma target CLKOUTEN DISABLED    -- no clock output
pragma target WDT      DISABLED    -- watchdog
pragma target BROWNOUT DISABLED    -- no brownout reset
pragma target FCMEN    DISABLED    -- no clock monitoring
pragma target CSWEN    ENABLED     -- allow writing OSCCON1 NOSC and NDIV
pragma target LVP      ENABLED     -- Low voltage programming
pragma target MCLR     EXTERNAL    -- external reset
OSCCON2 = 0x00                     -- 32 MHz and no division
--
-- Enable weak pull up for all ports since some inputs are not connected
WPUA = 0b1111_1111
WPUB = 0b1111_1111
WPUC = 0b1101_1111
WPUD = 0b1111_1111
WPUE = 0b0000_1111

enable_digital_io()
-- Give the hardware some time to stabilize.
_usec_delay(100_000)

-- -------------------------------- Pins ---------------------------------------
-- Declaration of the USART1 pins for the DFPlayer
alias pin_RX_direction  is pin_C7_direction  -- Pin 26 for 40 pin DIP
alias pin_TX_direction  is pin_C6_direction  -- Pin 25 for 40 pin DIP.

-- Declaration of the remapped USART2 pins for the PC.
alias pin_RX2_direction is pin_D2_direction  -- Pin 21 for 40 pin DIP
alias pin_TX2_direction is pin_D3_direction  -- Pin 22 for 40 pin DIP.

-- ------------------------- Constant declarations -----------------------------
const serial_hw_baudrate   = 9600   -- USART default speed for the DFPlayer.
const serial_hw2_baudrate  = 115200 -- USART speed for the terminal.

const byte MAX_INPUT = 20

-- -------------------------- Includes go here ---------------------------------

-- We need to include the serial library first followed by the include of the
-- DFPLayer so that this USART is used for communication with the DFPlayer.
include serial_hw_int_cts
include dfplayer

-- Terminal data goes via the second USART interface
include serial_hw2_int_cts
include print
include strings
include PPS

-- ------------------------- Variable declarations -----------------------------
var byte input_string[MAX_INPUT]
var byte command
var word parameter_1
var word parameter_2

-- ------------------------- Functions and Procedures --------------------------

-- Show the menu.
procedure show_menu() is

   print_crlf(serial_hw2_data)
   print_string(serial_hw2_data,"Select a command from the menu, followed by <CR><>LF>.\r\n")
   print_string(serial_hw2_data,"Note that spaces are required between command and parameter.\r\n")
   print_string(serial_hw2_data,"Parameters must be given as decimal numbers.\r\n")
   print_string(serial_hw2_data,"No checks are done if tracks and folders exist.\r\n")
   print_string(serial_hw2_data,"0: No command or just <CR><LF> shows this menu.\r\n")
   print_string(serial_hw2_data,"1 <Track 1..3000>: Play the given track.\r\n")
   print_string(serial_hw2_data,"2: Play the next track.\r\n")
   print_string(serial_hw2_data,"3: Play the previous track.\r\n")
   print_string(serial_hw2_data,"4: Play random.\r\n")
   print_string(serial_hw2_data,"5 <Folder 1..99> <Track 1..255>: Play the track from the given folder.\r\n")
   print_string(serial_hw2_data,"6 <Track 1..3000>: Play the given track from the MP3 folder.\r\n")
   print_string(serial_hw2_data,"7 <Folder 1..15 > <Track 1..3000>: Play the track from the given special 3000 track folder.\r\n")
   print_string(serial_hw2_data,"8 <Track 1..3000>: Play the given advertisement track.\r\n")
   print_string(serial_hw2_data,"9: Stop playing the advertisement.\r\n")
   print_string(serial_hw2_data,"10: Pause playing.\r\n")
   print_string(serial_hw2_data,"11: Resume playing.\r\n")
   print_string(serial_hw2_data,"12: Stop playing.\r\n")
   print_string(serial_hw2_data,"13: Start repeat play.\r\n")
   print_string(serial_hw2_data,"14: Stop repeat play.\r\n")
   print_string(serial_hw2_data,"15 <Track 1..3000>: Repeat playing the given track.\r\n")
   print_string(serial_hw2_data,"16 <Folder 1..99>: Repeat playing the given folder.\r\n")
   print_string(serial_hw2_data,"17: Start repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"18: Stop repeat playing the current track.\r\n")
   print_string(serial_hw2_data,"19 <Volume 0..30>: Set the output to the given volume.\r\n")
   print_string(serial_hw2_data,"20: Increment the volume by one step.\r\n")
   print_string(serial_hw2_data,"21: Decrement the volume by one step.\r\n")
   print_string(serial_hw2_data,"22 <Equalizer 0..5>: Set the equalizer to the given mode.\r\n")
   print_string(serial_hw2_data,"23 <Source 1..5>: Set playback using the given source.\r\n")
   print_string(serial_hw2_data,"24: Activate sleep mode.\r\n")
   print_string(serial_hw2_data,"25: Activate normal mode.\r\n")
   print_string(serial_hw2_data,"26: Reset player.\r\n")
   print_string(serial_hw2_data,"27: Set DAC on.\r\n")
   print_string(serial_hw2_data,"28: Set DAC off.\r\n")
   print_string(serial_hw2_data,"29: Check if player is playing.\r\n")
   print_string(serial_hw2_data,"30: Check if player is paused.\r\n")
   print_string(serial_hw2_data,"31: Check if player is stopped.\r\n")
   print_string(serial_hw2_data,"32: Check if player is sleeping.\r\n")
   print_string(serial_hw2_data,"33: Get the current volume.\r\n")
   print_string(serial_hw2_data,"34: Get the current equalizer setting.\r\n")
   print_string(serial_hw2_data,"35: Get the player mode.\r\n")
   print_string(serial_hw2_data,"36: Get the player version.\r\n")
   print_string(serial_hw2_data,"37: Get the number of USB tracks.\r\n")
   print_string(serial_hw2_data,"38: Get the number of SD tracks.\r\n")
   print_string(serial_hw2_data,"39: Get the number of FLASH tracks.\r\n")
   print_string(serial_hw2_data,"40: Get the current USB track.\r\n")
   print_string(serial_hw2_data,"41: Get the current SD track.\r\n")
   print_string(serial_hw2_data,"42: Get the current FLASH track.\r\n")
   print_string(serial_hw2_data,"43 <Folder 1..99>: Get the number of tracks in the given folder.\r\n")
   print_string(serial_hw2_data,"44: Get the number of folders on the current storage device.\r\n")
   print_crlf(serial_hw2_data)

end procedure

-- Get the input from the serial port and process it until CR + LF are received.
-- Input is stored in the global variable 'input_string'
function get_input() return bit is

   var byte counter
   var bit cr_received, lf_received

   cr_received = FALSE
   lf_received = FALSE
   -- Clear the processed string.
   for MAX_INPUT using counter loop
      input_string[counter] = 0
   end loop
   counter = 0
   while (counter < MAX_INPUT) & !cr_received &! lf_received loop
      if serial_hw2_read(input_string[counter]) then
         if (input_string[counter] == 0x0D) then
            cr_received = TRUE
         end if
         if (input_string[counter] == 0x0A) then
            lf_received = TRUE
         end if
         counter = counter + 1
      end if
   end loop

   return (counter != MAX_INPUT)

end function

-- Process the global variable 'input_string' and extract the command and if
-- present a parameter and store these in the corresponding global variables.
-- If data is incorrect the global parameter 'command' will be zero which will
-- result in showing the menu later.
procedure process_input() is

   var byte processed_string[MAX_INPUT]
   var byte counter, index
   var bit command_processed, parameter_1_processed, parameter_2_processed

   -- Clear the processed string
   for MAX_INPUT using index loop
      processed_string[index] = 0
   end loop
   counter = 0
   index = 0
   command = 0
   parameter_1 = 0
   parameter_2 = 0
   command_processed = FALSE
   parameter_1_processed = FALSE
   parameter_2_processed = FALSE
   while (counter < count(input_string)) loop
      -- Copy the number from the input.
      if (input_string[counter] >= "0" & input_string[counter] <= "9") then
         -- This is still a part of a number.
         processed_string[index] = input_string[counter]
         index = index + 1
      else
         -- We assume that we now have either a number or reached the end.
         if !command_processed then
            command = byte(string_to_dword(processed_string))
            -- If the data is incorrec the command will be 0 which means
            -- that we will show the menu.
            command_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_1_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_1 = word(string_to_dword(processed_string))
            parameter_1_processed = TRUE
            -- Clear the processed string.
            for MAX_INPUT using index loop
               processed_string[index] = 0
            end loop
            index = 0
         elsif !parameter_2_processed then
            -- Parameter is optional so no check if it is OK.
            parameter_2 = word(string_to_dword(processed_string))
            parameter_2_processed = TRUE
         end if
      end if
      counter = counter + 1
   end loop

end procedure

-- Execute the command, stored in the global variable 'command' with optional
-- a paramter in the global variable 'parameter'.
function execute_command() return bit is

   var word value
   var byte folder, track, temp
   var bit ok = TRUE

   case command of

      0: -- No DFPLayer command, show menu.
      block
         show_menu()
      end block

      1: -- Play Track with the given track number.
      block
         if (parameter_1 != 0) then
            dfplayer_play(parameter_1)
         else
            ok = FALSE
         end if
      end block

      2: -- Play the next track.
      block
         dfplayer_play_next()
      end block

      3: -- Play the previous track.
      block
         dfplayer_play_previous()
      end block

      4: -- Play random
      block
         dfplayer_play_random()
      end block

      5: -- Play track from folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            track = byte(parameter_2)
            dfplayer_play_folder(folder, track)
         else
            ok = FALSE
         end if
      end block

      6: -- Play the track from the MP3 folder.
      block
         if (parameter_1 != 0) then
            dfplayer_play_mp3_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      7: -- Play track from special 3000 track folder
      block
         if (parameter_1 != 0) & (parameter_2 != 0) then
            folder = byte(parameter_1)
            dfplayer_play_3000_folder(folder, parameter_2)
         else
            ok = FALSE
         end if
      end block

      8: -- Play the given advertisment track.
      block
         if (parameter_1 != 0) then
            dfplayer_play_advertisement(parameter_1)
         else
            ok = FALSE
         end if
      end block

      9: -- Stop playing the advertisement track.
      block
         dfplayer_stop_advertisement()
      end block

      10: -- Pause playing.
      block
         dfplayer_pause()
      end block

      11: -- Resume playing.
      block
         dfplayer_resume()
      end block

      12: -- Stop playing.
      block
         dfplayer_stop()
      end block

      13: -- Start repeat play.
      block
         dfplayer_start_repeat_play()
      end block

      14: -- Stop repeat play.
      block
         dfplayer_stop_repeat_play()
      end block

      15: -- Repeat playing the given track.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_track(parameter_1)
         else
            ok = FALSE
         end if
      end block

      16: -- Repeat playing the given folder.
      block
         if (parameter_1 != 0) then
            dfplayer_repeat_folder(parameter_1)
         else
            ok = FALSE
         end if
      end block

      17: -- Start repeat playing the current track.
      block
         dfplayer_start_repeat_current()
      end block

      18: -- Stop repeat playing the current track.
      block
         dfplayer_stop_repeat_current()
      end block

      19: -- Set the volume to the given value.
      block
          if (parameter_1 <= DFPLAYER_MAX_VOLUME) then
             temp = byte(parameter_1)
             dfplayer_set_volume(temp)
          else
             ok = FALSE
          end if
      end block

      20: -- Increment the volume.
      block
         dfplayer_increment_volume()
      end block

      21: -- Decrement the volume.
      block
         dfplayer_decrement_volume()
      end block

      22: -- Set the equalizer.
      block
          if (parameter_1 <= DFPLAYER_EQUALIZER_BASE ) then
             temp = byte(parameter_1)
             dfplayer_set_equalizer(temp)
          else
             ok = FALSE
          end if
      end block

      23: -- Set playback source
      block
          if (parameter_1 <= DFPLAYER_DEVICE_FLASH ) then
             temp = byte(parameter_1)
             dfplayer_set_playback_source(temp)
          else
             ok = FALSE
          end if
      end block

      24: -- Sleep mode.
      block
         dfplayer_sleep_mode()
      end block

      25: -- Normal mode.
      block
         dfplayer_normal_mode()
      end block

      26: -- Reset player.
      block
         dfplayer_reset()
      end block

      27: -- DAC on.
      block
         dfplayer_dac_on()
      end block

      28: -- DAC off.
      block
         dfplayer_dac_off()
      end block

      29: -- Check if player is playing.
      block
         if dfplayer_is_playing() then
             print_string(serial_hw2_data,"Player is playing.\r\n")
         else
             print_string(serial_hw2_data,"Player is not playing or could not be read.\r\n")
         end if
      end block

      30: -- Check if player is paused.
      block
         if dfplayer_is_paused() then
             print_string(serial_hw2_data,"Player is paused.\r\n")
         else
             print_string(serial_hw2_data,"Player is not paused or could not be read.\r\n")
         end if
      end block

      31: -- Check if player is stopped.
      block
         if dfplayer_is_stopped() then
             print_string(serial_hw2_data,"Player is stopped.\r\n")
         else
             print_string(serial_hw2_data,"Player is not stopped or could not be read.\r\n")
         end if
      end block

      32: -- Check if player is sleeping.
      block
         if dfplayer_is_sleeping() then
             print_string(serial_hw2_data,"Player is sleeping.\r\n")
         else
             print_string(serial_hw2_data,"Player is not sleeping or could not be read.\r\n")
         end if
      end block

      33: -- Get the volume.
      block
         if dfplayer_get_volume(temp) then
             print_string(serial_hw2_data,"The set volume is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The volume could not be read.\r\n")
         end if
      end block

      34: -- Get the equalizer
      block
         if dfplayer_get_equalizer(temp) then
             print_string(serial_hw2_data,"The equalizer is set to ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The equalizer setting could not be read.\r\n")
         end if
      end block

      35: -- Get the mode
      block
         if dfplayer_get_mode(temp) then
             print_string(serial_hw2_data,"The current mode is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current mode could not be read.\r\n")
         end if
      end block

      36: -- Get the version
      block
         if dfplayer_get_version(temp) then
             print_string(serial_hw2_data,"The version is ")
             print_byte_dec(serial_hw2_data,temp)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The version could not be read.\r\n")
         end if
      end block

      37: -- Get the number of USB tracks.
      block
         if dfplayer_get_nr_of_usb_tracks(value) then
             print_string(serial_hw2_data,"The number of USB tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of USB tracks could not be read.\r\n")
         end if
      end block

      38: -- Get the number of SD tracks.
      block
         if dfplayer_get_nr_of_sd_tracks(value) then
             print_string(serial_hw2_data,"The number of SD tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of SD tracks could not be read.\r\n")
         end if
      end block

      39: -- Get the number of FLASH tracks.
      block
         if dfplayer_get_nr_of_flash_tracks(value) then
             print_string(serial_hw2_data,"The number of FLASH tracks is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of FLASH tracks could not be read.\r\n")
         end if
      end block

      40: -- Get the current USB track.
      block
         if dfplayer_get_current_usb_track(value) then
             print_string(serial_hw2_data,"The current USB track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current USB track could not be read.\r\n")
         end if
      end block

      41: -- Get the current SD track.
      block
         if dfplayer_get_current_sd_track(value) then
             print_string(serial_hw2_data,"The current SD track is is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current SD track could not be read.\r\n")
         end if
      end block

      42: -- Get the current FLASH track.
      block
         if dfplayer_get_current_flash_track(value) then
             print_string(serial_hw2_data,"The current FLASH track is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The current FLASH track could not be read.\r\n")
         end if
      end block

      43: -- Get the number of tracks in the given folder
      block
         if (parameter_1 != 0) then
             if dfplayer_get_nr_of_tracks_in_folder(parameter_1, value) then
                print_string(serial_hw2_data,"The number of tracks in the given folder is ")
                print_word_dec(serial_hw2_data,value)
                print_string(serial_hw2_data,".\r\n")
            else
                print_string(serial_hw2_data,"The number of tracks could not be read from this folder.\r\n")
            end if
         else
            ok = FALSE
         end if
      end block

      44: -- Get the number of folders on the current storage device.
      block
         if dfplayer_get_nr_of_folders(value) then
             print_string(serial_hw2_data,"The number of folders on the current storage device is ")
             print_word_dec(serial_hw2_data,value)
             print_string(serial_hw2_data,".\r\n")
         else
             print_string(serial_hw2_data,"The number of folders on the current storage device could not be read.\r\n")
         end if
      end block

      -- Invalid command.
      otherwise ok = FALSE

   end case

   return ok

end function

-- -----------------------  Main program starts here ---------------------------

-- Re-assign the pins. Note: This must always be done to let it work even for
-- the default assignment.
pps_control_lock(FALSE)
RC6PPS = PPS_TX1       -- TX1 re-assigned to C6  (default)
RX1PPS = PPS_RC7       -- C7 re-assigned to RX1  (default)
RD3PPS = PPS_TX2       -- TX2 re-assigned to D3
RX2PPS = PPS_RD2       -- D2  re-assigned to RX2
pps_control_lock(TRUE)

-- Initialize all libraries.
serial_hw_init()
serial_hw2_init()
dfplayer_init()

print_crlf(serial_hw2_data)
print_string(serial_hw2_data,"Sample program for the DFPlayer.\r\n\r\n")

-- We generate a menu from which actions can be started.
show_menu()

forever loop

   if get_input() then
      process_input()
      if execute_command() then
         print_string(serial_hw2_data,"Command executed!\r\n\r\n")
      else
         print_string(serial_hw2_data,"Invalid command!\r\n\r\n")
      end if
   else
      print_string(serial_hw2_data,"Input too long!\r\n\r\n")
   end if

end loop

Generated by JALlib CHM Help System | Source: strings.jal


strings.jal - JALLIB Library Documentation

strings.jal JALLIB LIBRARY

Title

Strings Library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by: Oliver "Kiste" Seitz

Compiler

>=2.4k

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for managing strings.

Routines

  • string_compare - Function returns bit
  • string_compare_case - Function returns bit
  • string_compare_mid - Function returns bit
  • string_compare_mid_case - Function returns bit
  • string_length - Function returns byte
  • string_to_dword - Function returns dword
  • string_to_dword_old - Function returns dword
  • string_to_sdword - Function returns sdword


t6963_init - JALlib Procedures Help

t6963_init JALLIB PROCEDURE

Signature

procedure t6963_init() is

Description

Initialize t6963
Control signals use negative logic (high is inactive)
All control pins must be set for output by the application
Both text and graphics display are active

Include

To use this procedure, include the library:

include glcd_t6963

Parameters

None

Return Value

None

Example

From sample file: 16f877a_glcd_t6963.jal

-- ------------------------------------------------------
-- Title: Test glcd_t6963c_library with a pic16f877a
--
-- Author: Rob Hamerling, Copyright (c) 2015..2015, all rights reserved.
--
-- Adapted-by:
--
-- Compiler:2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
--    Elementary tests of the glcd_t6963c library!
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
include 16f877a                           -- target PICmicro
--
pragma target clock    4_000_000          -- oscillator frequency
--
pragma target OSC      XT                 -- resonator
pragma target WDT      DISABLED           -- watchdog
pragma target PWRTE    ENABLED            -- power-on delay
pragma target BROWNOUT DISABLED           -- no brownout reset
pragma target LVP      ENABLED            -- allow low voltage programming
--
enable_digital_io()                       -- make all pins digital I/O
--
include delay                             -- library with delay procedures
include print

-- --- serial hardware setup ---------------------------------

const serial_hw_baudrate = 19200
alias serial_ctsinv      is pin_B0        -- CTS incoming flow ctl
var   bit serial_overflow_discard = FALSE     -- no transmit buffer overflow
pin_rx_direction = INPUT
pin_tx_direction = OUTPUT
pin_B0_direction = OUTPUT

include serial_hw_int_cts                 -- serial library

serial_hw_init()

-- --- setup the GLCD --------------------------------------

alias t6963_dataport is portD
alias t6963_dataport_direction is portD_direction

-- control signal pins
alias t6963_wr		is pin_C0
alias t6963_rd		is pin_C1
alias t6963_ce		is pin_C2
alias t6963_cd		is pin_C3
alias t6963_reset	is pin_C4
-- alias t6963_fs		is pin_C5

-- all control pins are output
pin_C0_direction = OUTPUT
pin_C1_direction = OUTPUT
pin_C2_direction = OUTPUT
pin_C3_direction = OUTPUT
pin_C4_direction = OUTPUT
pin_C5_direction = INPUT

-- general display properties

const byte T6963_X_PIXELS	  = 240
const byte T6963_Y_PIXELS    = 64
const byte T6963_FONT_WIDTH  = 6
const bit  T6963_CLIPPING    = TRUE
var   bit  t6963_pen_color   = ON            -- pixel ON (to clear a pixel: OFF)

include glcd_t6963                           -- T6963 device specific library

t6963_init()                                 -- init t6963 library

-- glcd aliases for public t6963 procedures, functions, etc.
-- These generic names are used in this sample, and
-- some of these are also needed by the glcd_common library

alias  glcd_set_mode            is t6963_set_mode
alias  glcd_display_mode        is t6963_display_mode
alias  glcd_clear_text          is t6963_clear_text
alias  glcd_clear_graphics      is t6963_clear_graphics
alias  glcd_clear_screen        is t6963_clear_screen
alias  glcd_read_char           is t6963_read_char
alias  glcd_read_next_char      is t6963_read_next_char
alias  glcd_write_char          is t6963_write_char
alias  glcd_write_next_char     is t6963_write_next_char
alias  glcd_write_string        is t6963_write_string
alias  glcd_set_cursor_pattern  is t6963_set_cursor_pattern
alias  glcd_set_cursor_position is t6963_set_cursor_position
alias  glcd_set_attribute       is t6963_set_attribute
alias  glcd_write_pixel         is t6963_write_pixel
alias  glcd_read_cg_memory      is t6963_read_cg_memory
alias  glcd_write_cg_memory     is t6963_write_cg_memory

alias  GLCD_X_PIXELS	           is T6963_X_PIXELS
alias  GLCD_Y_PIXELS            is T6963_Y_PIXELS
alias  GLCD_FONT_WIDTH          is T6963_FONT_WIDTH
alias  GLCD_CLIPPING            is T6963_CLIPPING
alias  glcd_pen_color           is t6963_pen_color

include glcd_common                          -- library for lines, circles, etc.

print_string(serial_hw_data, PICTYPE)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_memsize)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_graphics_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home)
serial_hw_data = " "
print_word_dec(serial_hw_data, t6963_cg_home >> 11)
serial_hw_data = " "

-- ---------------------------------------------------------

glcd_clear_screen()

glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- display only text

glcd_write_char(8,1,"<")                     -- start at 9th column 9, 2nd line
glcd_write_next_char("T")
glcd_write_next_char("6")
glcd_write_next_char("9")
glcd_write_next_char("6")
glcd_write_next_char("3")
glcd_write_next_char("c")
glcd_write_next_char(">")

delay_100ms(20)

var byte i,j, x,y

glcd_write_char(0,0," ")
for 256 using i loop                         -- complete ASCII range
   glcd_write_next_char(i)
end loop
delay_100ms(60)

glcd_clear_text()
glcd_write_string(4,3,"String AUTO write")
delay_100ms(20)

glcd_clear_graphics()
glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON | T6963_DISPLAY_TEXT_ON)  -- required for attributes
glcd_set_attribute(4,3,0b00000101, 11)       -- reverse video (may change mode!)
delay_100ms(20)

glcd_clear_graphics()
glcd_set_mode(T6963_SET_MODE_OR)             -- back from text only with attributes
glcd_pen_color = ON                          -- set pixels
for GLCD_X_PIXELS using x loop               -- equivalent of glcd_line()
   y = x % GLCD_Y_PIXELS
   glcd_write_pixel(x, y)
end loop
delay_100ms(20)

glcd_clear_graphics()
x = 0
while (x < (GLCD_X_PIXELS - GLCD_Y_PIXELS)) loop
   glcd_pen_color = ON
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- draw
   delay_100ms(2)
   glcd_pen_color = OFF
   glcd_circle(x + GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2 - 1)    -- erase
   x = x + 5
end loop
delay_100ms(20)

glcd_pen_color = ON
glcd_box(0,0, GLCD_Y_PIXELS/2, GLCD_Y_PIXELS/2)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_EXOR)        -- reverse video with overwritten text
glcd_box_fill(GLCD_X_PIXELS/4, GLCD_Y_PIXELS/4, GLCD_X_PIXELS/2, GLCD_Y_PIXELS - 1)
delay_100ms(20)

glcd_set_mode(T6963_SET_MODE_OR)
for 3 loop
   glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- only text
   delay_100ms(10)
   glcd_display_mode(T6963_DISPLAY_GRAPHICS_ON)   -- only graphics
   delay_100ms(10)
end loop

glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_GRAPHICS_ON)  -- mixed
glcd_clear_screen()

glcd_clear_text()
var byte euro[16] = {0b0000_0000,         -- Euro
                     0b0000_1110,
                     0b0001_0001,
                     0b0011_1100,
                     0b0001_0000,
                     0b0011_1100,
                     0b0001_0001,
                     0b0000_1110,

                     0b1111_1110,         -- slash in reverse video
                     0b1111_1101,
                     0b1111_1011,
                     0b1111_0111,
                     0b1110_1111,
                     0b1101_1111,
                     0b1011_1111,
                     0b0111_1111}

glcd_write_cg_memory(0x80, euro)          -- define the Euro character in CG-RAM
glcd_write_char(25, 6, 0x80)              -- display the Euro character
glcd_write_char(27, 6, 0x81)              -- display 2nd CG char
delay_100ms(30)

var byte cg[] = {0,1,2,3,4,5,6,7, 8,9,0,1,2,3,4,5}
glcd_read_cg_memory(0x80, cg)
for count(cg) using i loop
   serial_hw_data = cg[i]
end loop

glcd_write_string(1,1, "Different cursor patterns (blinking)")
glcd_display_mode(T6963_DISPLAY_TEXT_ON | T6963_DISPLAY_CURSOR_ON | T6963_DISPLAY_CURSOR_BLINK_ON)
for 8 using i loop
   glcd_set_cursor_pattern(i + 1)
   glcd_set_cursor_position(i, 2)
   delay_100ms(20)
end loop

glcd_clear_screen()
glcd_display_mode(T6963_DISPLAY_TEXT_ON)     -- no cursor, no graphics!
glcd_write_string(0,0, "Awaiting data from serial port")

alias  led       is pin_A0                   -- alias for pin with LED
pin_A0_direction = OUTPUT

alias button is pin_A4                       -- push button for ??
pin_A4_direction = INPUT

x = 0
y = 0
--
forever loop
   var byte char, back
   if (serial_hw_read(char) == TRUE) then
      serial_hw_write(char)                  -- echo
      if ((x == 0) & (y == 0)) then
         glcd_clear_text()
      end if
      glcd_write_char(x,y,char)
      back = glcd_read_char(x,y)
      serial_hw_write(0x00)
      serial_hw_write(back)
      x = x + 1
      if (x >= GLCD_X_PIXELS / GLCD_FONT_WIDTH) then
         x = 0
         y = y + 1
         if (y >= (GLCD_Y_PIXELS / 8)) then
            y = 0
         end if
      end if
   elsif (button == FALSE) then
       serial_hw_write(".")
       delay_100ms(1)
   else
      led = ON
      delay_100ms(1)
      led = OFF
      delay_100ms(1)
   end if
end loop
--

Generated by JALlib CHM Help System | Source: glcd_t6963.jal


Tasks - JAL Language Syntax Reference

Tasks JALV2 SYNTAX

Syntax

task
identifier
[ '(' parameter list ') ' ]
is

Description

JALv2 introduces the concept of TASKs which are a form of co-operative multi-tasking. Unlike preemptive multi-tasking, where control passes from one task to another automatically, control will only pass when a task specifically allows it. Tasks can only be started by the main program, or within another task. Tasks are started with: When a task is ready to allow another to run, it executes: To end the task, simply Only one copy of the body of a task should be run at a time. Attempting to run two copies of the same task simultaneously will cause an error.
start identifier [ '(' parameter list ')' ]

suspend

Example

include 18f4620
pragma target clock 20_000_000

-- Define pins
pin_a0_direction = output
pin_a1_direction = output
pin_a2_direction = output

var bit led1_state
var bit led2_state
var bit led3_state

-- Task 1: Blink LED on A0
task blink_led1 is
   forever loop
      led1_state = !led1_state
      pin_a0 = led1_state
      _usec_delay(500000)
      suspend
   end loop
end task

-- Task 2: Blink LED on A1
task blink_led2 is
   forever loop
      led2_state = !led2_state
      pin_a1 = led2_state
      _usec_delay(250000)
      suspend
   end loop
end task

-- Task 3: Blink LED on A2
task blink_led3 is
   forever loop
      led3_state = !led3_state
      pin_a2 = led3_state
      _usec_delay(100000)
      suspend
   end loop
end task

-- Main program (also a task)
forever loop
   start blink_led1
   start blink_led2
   start blink_led3
   suspend
end loop

Generated by JAL Syntax Documentation System | Source: DITA


tc77_read_celsius_sbyte - JALlib Procedures Help

tc77_read_celsius_sbyte JALLIB PROCEDURE

Signature

procedure tc77_read_celsius_sbyte(sbyte out temperature) is

Description

procedures for compatibility

Include

To use this procedure, include the library:

include temperature_tc77

Parameters

  • temperature - sbyte out

Return Value

None

Example

From sample file: 16f876a_tc77.jal

-- Title: read TC77 temperatures, show on LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the temperature in Celsius
-- with different precisions from the TC77 sensor.
-- It demonstrates the different routines in the TC77 library.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock      20_000_000  -- 20 MHz xtal
pragma target OSC       HS
pragma target WDT       disabled    -- no watchdog, please
pragma target LVP       enabled     -- allow low voltage programming

enable_digital_io()                 -- no analog pins here

-- ------------------- INCLUDE LIBRARIES --------------------------
const byte LCD_ROWS = 4
const byte LCD_CHARS = 20

alias LCD_RS           is pin_b5          -- LCD command/data select.
pin_b5_direction = output
alias LCD_EN           is pin_b4          -- LCD data trigger
pin_b4_direction = output

alias lcd_dataport    is portb_low        -- LCD data nibble
portb_low_direction = all_output
include lcd_hd44780_4                     -- LCD library with 4 data lines
lcd_init()

include print                             -- nice formatted output
include format                            -- more nice formatted output

alias CS                 is pin_a0        -- chip select of TC77, active low
CS                       = high
pin_a0_direction         = output
alias SIO                is pin_a2        -- data in/out of TC77
pin_a2_direction         = input          -- only used as input here
alias SCK                is pin_a1        -- clock of TC77
pin_a1_direction         = output
include temperature_tc77                  -- TC77 library

-- ------------------- VARIABLES --------------------------------------

var word    temperature_raw             -- raw 13-bit value, with sign
var sbyte   temperature_8               -- signed Celsius, precision 1C
var sword   temperature_16              -- signed Celsius, precision 0.01C
var sdword  temperature_32              -- signed Celsius, precision 0.0001C

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()

forever loop
   lcd_cursor_position(0,0)
   CS = low
   tc77_read_raw(temperature_raw)
   CS = high
   print_word_bin(lcd, temperature_raw)

   lcd_cursor_position(1,0)
   CS = low
   tc77_read_celsius_sbyte(temperature_8)
   CS = high
   print_sbyte_dec(lcd, temperature_8)    -- prints minus if below 0
   lcd =" "                               -- to wipe out old digits

   lcd_cursor_position(0, 20)                   -- row 3, position = 1
   CS = low
   tc77_read_celsius_sword(temperature_16)
   CS = high
   format_sword_dec(lcd, temperature_16, 5, 2)  -- width 6: -xx.xx or xxx.xx
   lcd =" "

   lcd_cursor_position(1, 20)                   -- row 4, position = 1
   CS = low
   tc77_read_celsius_sdword(temperature_32)
   CS = high
   format_sdword_dec(lcd, temperature_32, 7, 4)  -- 8 wide: -xx.xxxx or xxx.xxxx
   lcd = " "

   delay_100ms(2)                         -- for proper display viewing

end loop

Generated by JALlib CHM Help System | Source: temperature_tc77.jal


tc77_read_celsius_sdword - JALlib Procedures Help

tc77_read_celsius_sdword JALLIB PROCEDURE

Signature

procedure tc77_read_celsius_sdword(sdword out temperature) is

Description

No description available.

Include

To use this procedure, include the library:

include temperature_tc77

Parameters

  • temperature - sdword out

Return Value

None

Example

From sample file: 16f876a_tc77.jal

-- Title: read TC77 temperatures, show on LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the temperature in Celsius
-- with different precisions from the TC77 sensor.
-- It demonstrates the different routines in the TC77 library.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock      20_000_000  -- 20 MHz xtal
pragma target OSC       HS
pragma target WDT       disabled    -- no watchdog, please
pragma target LVP       enabled     -- allow low voltage programming

enable_digital_io()                 -- no analog pins here

-- ------------------- INCLUDE LIBRARIES --------------------------
const byte LCD_ROWS = 4
const byte LCD_CHARS = 20

alias LCD_RS           is pin_b5          -- LCD command/data select.
pin_b5_direction = output
alias LCD_EN           is pin_b4          -- LCD data trigger
pin_b4_direction = output

alias lcd_dataport    is portb_low        -- LCD data nibble
portb_low_direction = all_output
include lcd_hd44780_4                     -- LCD library with 4 data lines
lcd_init()

include print                             -- nice formatted output
include format                            -- more nice formatted output

alias CS                 is pin_a0        -- chip select of TC77, active low
CS                       = high
pin_a0_direction         = output
alias SIO                is pin_a2        -- data in/out of TC77
pin_a2_direction         = input          -- only used as input here
alias SCK                is pin_a1        -- clock of TC77
pin_a1_direction         = output
include temperature_tc77                  -- TC77 library

-- ------------------- VARIABLES --------------------------------------

var word    temperature_raw             -- raw 13-bit value, with sign
var sbyte   temperature_8               -- signed Celsius, precision 1C
var sword   temperature_16              -- signed Celsius, precision 0.01C
var sdword  temperature_32              -- signed Celsius, precision 0.0001C

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()

forever loop
   lcd_cursor_position(0,0)
   CS = low
   tc77_read_raw(temperature_raw)
   CS = high
   print_word_bin(lcd, temperature_raw)

   lcd_cursor_position(1,0)
   CS = low
   tc77_read_celsius_sbyte(temperature_8)
   CS = high
   print_sbyte_dec(lcd, temperature_8)    -- prints minus if below 0
   lcd =" "                               -- to wipe out old digits

   lcd_cursor_position(0, 20)                   -- row 3, position = 1
   CS = low
   tc77_read_celsius_sword(temperature_16)
   CS = high
   format_sword_dec(lcd, temperature_16, 5, 2)  -- width 6: -xx.xx or xxx.xx
   lcd =" "

   lcd_cursor_position(1, 20)                   -- row 4, position = 1
   CS = low
   tc77_read_celsius_sdword(temperature_32)
   CS = high
   format_sdword_dec(lcd, temperature_32, 7, 4)  -- 8 wide: -xx.xxxx or xxx.xxxx
   lcd = " "

   delay_100ms(2)                         -- for proper display viewing

end loop

Generated by JALlib CHM Help System | Source: temperature_tc77.jal


tc77_read_celsius_sword - JALlib Procedures Help

tc77_read_celsius_sword JALLIB PROCEDURE

Signature

procedure tc77_read_celsius_sword(sword out temperature) is

Description

No description available.

Include

To use this procedure, include the library:

include temperature_tc77

Parameters

  • temperature - sword out

Return Value

None

Example

From sample file: 16f876a_tc77.jal

-- Title: read TC77 temperatures, show on LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the temperature in Celsius
-- with different precisions from the TC77 sensor.
-- It demonstrates the different routines in the TC77 library.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock      20_000_000  -- 20 MHz xtal
pragma target OSC       HS
pragma target WDT       disabled    -- no watchdog, please
pragma target LVP       enabled     -- allow low voltage programming

enable_digital_io()                 -- no analog pins here

-- ------------------- INCLUDE LIBRARIES --------------------------
const byte LCD_ROWS = 4
const byte LCD_CHARS = 20

alias LCD_RS           is pin_b5          -- LCD command/data select.
pin_b5_direction = output
alias LCD_EN           is pin_b4          -- LCD data trigger
pin_b4_direction = output

alias lcd_dataport    is portb_low        -- LCD data nibble
portb_low_direction = all_output
include lcd_hd44780_4                     -- LCD library with 4 data lines
lcd_init()

include print                             -- nice formatted output
include format                            -- more nice formatted output

alias CS                 is pin_a0        -- chip select of TC77, active low
CS                       = high
pin_a0_direction         = output
alias SIO                is pin_a2        -- data in/out of TC77
pin_a2_direction         = input          -- only used as input here
alias SCK                is pin_a1        -- clock of TC77
pin_a1_direction         = output
include temperature_tc77                  -- TC77 library

-- ------------------- VARIABLES --------------------------------------

var word    temperature_raw             -- raw 13-bit value, with sign
var sbyte   temperature_8               -- signed Celsius, precision 1C
var sword   temperature_16              -- signed Celsius, precision 0.01C
var sdword  temperature_32              -- signed Celsius, precision 0.0001C

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()

forever loop
   lcd_cursor_position(0,0)
   CS = low
   tc77_read_raw(temperature_raw)
   CS = high
   print_word_bin(lcd, temperature_raw)

   lcd_cursor_position(1,0)
   CS = low
   tc77_read_celsius_sbyte(temperature_8)
   CS = high
   print_sbyte_dec(lcd, temperature_8)    -- prints minus if below 0
   lcd =" "                               -- to wipe out old digits

   lcd_cursor_position(0, 20)                   -- row 3, position = 1
   CS = low
   tc77_read_celsius_sword(temperature_16)
   CS = high
   format_sword_dec(lcd, temperature_16, 5, 2)  -- width 6: -xx.xx or xxx.xx
   lcd =" "

   lcd_cursor_position(1, 20)                   -- row 4, position = 1
   CS = low
   tc77_read_celsius_sdword(temperature_32)
   CS = high
   format_sdword_dec(lcd, temperature_32, 7, 4)  -- 8 wide: -xx.xxxx or xxx.xxxx
   lcd = " "

   delay_100ms(2)                         -- for proper display viewing

end loop

Generated by JALlib CHM Help System | Source: temperature_tc77.jal


tc77_read_raw - JALlib Procedures Help

tc77_read_raw JALLIB PROCEDURE

Signature

procedure tc77_read_raw(word out raw) is

Description

Read raw data from TC77

Include

To use this procedure, include the library:

include temperature_tc77

Parameters

  • raw - word out

Return Value

None

Example

From sample file: 16f876a_tc77.jal

-- Title: read TC77 temperatures, show on LCD
-- Author: Eur van Andel, eur@fiwihex.nl Copyright (c) 2008
-- Adapted-by: Albert Faber
-- Compiler: =2.4l
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: this sample shows how to read the temperature in Celsius
-- with different precisions from the TC77 sensor.
-- It demonstrates the different routines in the TC77 library.
--
-- This file has been generated by hand (manually maintained)
--

-- select PIC
include 16f876a

pragma target clock      20_000_000  -- 20 MHz xtal
pragma target OSC       HS
pragma target WDT       disabled    -- no watchdog, please
pragma target LVP       enabled     -- allow low voltage programming

enable_digital_io()                 -- no analog pins here

-- ------------------- INCLUDE LIBRARIES --------------------------
const byte LCD_ROWS = 4
const byte LCD_CHARS = 20

alias LCD_RS           is pin_b5          -- LCD command/data select.
pin_b5_direction = output
alias LCD_EN           is pin_b4          -- LCD data trigger
pin_b4_direction = output

alias lcd_dataport    is portb_low        -- LCD data nibble
portb_low_direction = all_output
include lcd_hd44780_4                     -- LCD library with 4 data lines
lcd_init()

include print                             -- nice formatted output
include format                            -- more nice formatted output

alias CS                 is pin_a0        -- chip select of TC77, active low
CS                       = high
pin_a0_direction         = output
alias SIO                is pin_a2        -- data in/out of TC77
pin_a2_direction         = input          -- only used as input here
alias SCK                is pin_a1        -- clock of TC77
pin_a1_direction         = output
include temperature_tc77                  -- TC77 library

-- ------------------- VARIABLES --------------------------------------

var word    temperature_raw             -- raw 13-bit value, with sign
var sbyte   temperature_8               -- signed Celsius, precision 1C
var sword   temperature_16              -- signed Celsius, precision 0.01C
var sdword  temperature_32              -- signed Celsius, precision 0.0001C

-- --------------- START PROGRAM ---------------------------

lcd_clear_screen()

forever loop
   lcd_cursor_position(0,0)
   CS = low
   tc77_read_raw(temperature_raw)
   CS = high
   print_word_bin(lcd, temperature_raw)

   lcd_cursor_position(1,0)
   CS = low
   tc77_read_celsius_sbyte(temperature_8)
   CS = high
   print_sbyte_dec(lcd, temperature_8)    -- prints minus if below 0
   lcd =" "                               -- to wipe out old digits

   lcd_cursor_position(0, 20)                   -- row 3, position = 1
   CS = low
   tc77_read_celsius_sword(temperature_16)
   CS = high
   format_sword_dec(lcd, temperature_16, 5, 2)  -- width 6: -xx.xx or xxx.xx
   lcd =" "

   lcd_cursor_position(1, 20)                   -- row 4, position = 1
   CS = low
   tc77_read_celsius_sdword(temperature_32)
   CS = high
   format_sdword_dec(lcd, temperature_32, 7, 4)  -- 8 wide: -xx.xxxx or xxx.xxxx
   lcd = " "

   delay_100ms(2)                         -- for proper display viewing

end loop

Generated by JALlib CHM Help System | Source: temperature_tc77.jal


tcp.jal - JALLIB Library Documentation

tcp.jal JALLIB LIBRARY

Title

TCP - TRANSMISSION CONTROL PROTOCOL BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

implements TCP/IP

Notes

Works, but may still have issues.
Packet must fit within transmit buffer, I have not tested large transfers.
Todo:
add checksum verify on incomming TCP packets

Sources

http://www.faqs.org/rfcs/rfc793.html
http://www.8051projects.net/out.php?link=http://www.sics.se/~adam/uip/index.php/Main_Page

Constants and Variables

tcp_header_length - var byte = 20

Routines

  • print_tcp_socket_info - Procedure
  • tcp_connect - Procedure
  • tcp_data'get - Function returns byte
  • tcp_data'put - Procedure
  • tcp_error'get - Function returns byte
  • tcp_init - Procedure
  • tcp_read_packet - Procedure
  • tcp_send - Procedure
  • tcp_send_ack - Procedure
  • tcp_set_checksum - Procedure
  • tcp_socket_create - Function returns byte
  • tcp_socket_remove - Procedure


tcp_connect - JALlib Procedures Help

tcp_connect JALLIB PROCEDURE

Signature

procedure tcp_connect(byte in socket) is

Description

Connect to a TCP server. Input a blank variable to be used as a socket name.

Include

To use this procedure, include the library:

include tcp

Parameters

  • socket - byte in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: tcp.jal


tcp_init - JALlib Procedures Help

tcp_init JALLIB PROCEDURE

Signature

procedure tcp_init() is

Description

Init procedure

Include

To use this procedure, include the library:

include tcp

Parameters

None

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: tcp.jal


tcp_send - JALlib Procedures Help

tcp_send JALLIB PROCEDURE

Signature

procedure tcp_send(byte in socket, word in data_size) is

Description

Send a TCP packet

Include

To use this procedure, include the library:

include tcp

Parameters

  • socket - byte in
  • data_size - word in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: tcp.jal


tcp_send_ack - JALlib Procedures Help

tcp_send_ack JALLIB PROCEDURE

Signature

procedure tcp_send_ack(byte in socket, word in data_size) is

Description

Send ack or reply to TCP

Include

To use this procedure, include the library:

include tcp

Parameters

  • socket - byte in
  • data_size - word in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: tcp.jal


tcp_socket_create - JALlib Procedures Help

tcp_socket_create JALLIB FUNCTION

Signature

function tcp_socket_create(word in local_port, word in remote_port) return byte is

Description

Create a new socket. If a socket was not created, var tcp_error gets set.
remote_port - the port number the remote server uses
local_port - any port number that is avalable locally.

Include

To use this procedure, include the library:

include tcp

Parameters

  • local_port - word in
  • remote_port - word in

Return Value

byte - Function return value

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: tcp.jal


temperature_humidity_dht11.jal - JALLIB Library Documentation

temperature_humidity_dht11.jal JALLIB LIBRARY

Title

DHT11 library

Author

Sebastien Lelong, Copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

DHT11 is a cheap temperature and humidity sensor. This library
accesses this module and reads values from it.
.
Accessing the module is quite straight forward and requires one signal
pin and a pullup resistor. This pin will be set as output and input by the
library itself, and is used to activate the sensor, then actually getting
values. Temp & humidity values comes in one frame from the sensor. Library
split both value type and set global variables. This means these global
variables store the last accessed value. Variables are word storing floating
point value. Eg: when humidity is 652, then it means its 65.2
.
This library will also work with the more accurate DHT22 version, just declare
a "USE_DHT22" const set to true. DHT22 is also known as RHT03. Careful though,
most people report RHT03 needs 5V to properly work, and DHT22 at least 3V3. If
you receive timeouts with these when powered with 3V3, give a try with 5V.

Sources

- datasheet: http://www.robotshop.com/PDF/dht11.pdf
- arduino playground: http://arduino.cc/playground/Main/DHT11Lib

Constants and Variables

DHT11_OK - const byte = 0
DHT11_ERR - const byte = 1
DHT11_TIMEOUT - const byte = 2
dht11_temperature - var word = 0
dht11_humidity - var word = 0
DHT11_TIMEOUT_TRY - const word = 1000

Routines

  • dht11_read - Function returns byte


temperature_max6675.jal - JALLIB Library Documentation

temperature_max6675.jal JALLIB LIBRARY

Title

Library for max6675 Temperature for K-Thermocouple with SPI.

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for max6675 Temperature IC to convert a
Cold-Junction-Compensated K-Thermocouple to a
Digital reading (0C to +1024C).

Sources

http://datasheets.maximintegrated.com/en/ds/MAX6675.pdf

Routines

  • max6675_temp_c - Function returns word
  • max6675_temp_f - Function returns word


temperature_sht.jal - JALLIB Library Documentation

temperature_sht.jal JALLIB LIBRARY

Title

SHTxx, for Sensirion humidity and temperature sensors

Author

Eur van Andel, eur@fiwihex.nl Copyright (c) 2008

Compiler

=2.4h

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

The Sensirion SHT1x/SHT7x is a single chip relative humidity and
temperature multi sensor module comprising a calibrated digital output.
It comes in 5 flavors, with different accuracy and package style:
sensor hum acc temp acc package
SHT10 4.5% 0.5C SMD (LCC)
SHT11 3.0% 0.4C SMD (LCC)
SHT15 2.0% 0.3C SMD (LCC)
SHT71 3.0% 0.4C 4-pin single-in-line
SHT75 1.8% 0.3C 4-pin single-in-line
all consist of the same silicon: the less accurate models are sold cheaper.
My experience is mixed: I've seen some consistent +2C offset in temperature,
but good humidty measurements. The 4-pin package breaks when you touch it.
The SMD package has naked tracks underneath: you can't route under it!
If exposed to >95% RH for 10 minutes, these sensors will go beserk and need
<60% RH for an hour to recover. You might try heating them.
protocol is close to I2C, but not the same. Remember to pull up DATA.
0b0000_0011 starts temperature measurement
0b0000_0101 starts humidity measurement
device returns three bytes: MSB, LSB and CRC
this library doesn't perform any CRC check
Declarations:
var bit SHT_SCK -- output pin, clock signal to sensor
var bit SHT_DATA -- data pin, data flows in both directions
var bit SHT_DATA_DIR -- direction of data pin
Still to do: switching heating on/off

Sources

http://www.sensirion.com/en/01_humidity_sensors/00_humidity_sensors.htm

Constants and Variables

CRC - var byte
tmp - var sdword
counter - var byte = 41

Routines

  • read_celsius_temp_sht - Procedure
  • read_centicelsius_temp_raw_sht - Procedure
  • read_centicelsius_temp_sht - Procedure
  • read_hum_sht - Procedure
  • read_hum_word_sht - Procedure
  • read_raw_hum_sht - Procedure
  • read_raw_temp_sht - Procedure
  • sht_conn_reset - Procedure
  • sht_get_data - Procedure
  • sht_put_ack - Procedure
  • sht_put_data - Procedure
  • sht_reset - Procedure
  • sht_start - Procedure
  • sht_wait_ack - Procedure
  • sht_wait_ack_out - Procedure


temperature_tc77.jal - JALLIB Library Documentation

temperature_tc77.jal JALLIB LIBRARY

Title

TC77 temperature library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library reads temperature from TC77 through SPI.
TC77 has a resolution of 0.0625C from -55C to +125C

Notes

This is a complete re-write of the orignal jallib TC77 library
written by Eur van Andel.
Improvements:
Uses pesudo variables
tiny bit less code/ram usage.
cs line controlled by library (optional)
no ASM
Compatible with the jallib SPI library (hardware or software)
Less code used when using multiple devices since SPI code is shared.

Sources

TC77 temperature sensor library by Eur van Andel
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010750

Constants and Variables

TC77_CS_IN_LIB - const byte = FALSE

Routines

  • tc77_celsius_sbyte'get - Function returns sbyte
  • tc77_celsius_sdword'get - Function returns sdword
  • tc77_celsius_sword'get - Function returns sword
  • tc77_read_celsius_sbyte - Procedure
  • tc77_read_celsius_sdword - Procedure
  • tc77_read_celsius_sword - Procedure
  • tc77_read_raw - Procedure


timer0.jal - JALLIB Library Documentation

timer0.jal JALLIB LIBRARY

Title

Timer library (Timer Alias for timer 0)

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Provides a standard way to use timers.

Constants and Variables

TIMER0_IS_BITS - const byte = 16
TIMER0_IS_BITS - const byte = 8
TIMER0_IS_BITS - const byte = 8

Routines

  • timer_init - Procedure


timer0_isr_init - JALlib Procedures Help

timer0_isr_init JALLIB PROCEDURE

Signature

procedure timer0_isr_init() is

Description

No description available.

Include

To use this procedure, include the library:

include timer0_isr_interval

Parameters

None

Return Value

None

Example

From sample file: 18f14k50_timer0_interval.jal

-- ----------------------------------------------------------------------------
-- Title: test timer0 interval
--
-- Author: Joep Suijs, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: test the library timero_isr_interval
-- --
-- This file defines a test for JALLIB testing, using a test-board
--  defined by a BOARD file .
--
-- ----------------------------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f14k50_af.jal
--    * test : test_timer0_interval.jal
--

;@jallib section chipdef
-- chip setup
include 18f14k50

-- This file is the setup for my homebrew, 18f14k50 board
-- Currently it is a bare board, with just a PIC and a couple of headers
-- A 12 MHz external crystal and 15pf caps connected to OSC1/2
-- pin 17 (Vusb) with a 220 nF capacitor to the ground
-- The connection between PC and the 18F14k50
-- +5v to power the board (don't forget 100nf decoupling cap
-- data- wire to pin 18 (D-)
-- data+ wire to pin 19 (D+)
-- ground wire to the Vss of the PIC
-- even though the external crystal is 12 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz
pragma target clock       48_000_000

-- fuses
pragma target CPUDIV        P1              -- NO_CPU_SYSTEM_CLOCK_DIVIDE
pragma target USBDIV        P1              -- USB_CLOCK_COMES_DIRECTLY_FROM_THE_OSC1_OSC2_OSCILLATOR_BLOCK_NO_DIVIDE
pragma target OSC           HS
pragma target PLLEN         ENABLED         -- OSCILLATOR_MULTIPLIED_BY_4
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED        -- power up timer
pragma target BROWNOUT      DISABLED        -- no brownout detection
pragma target VOLTAGE       V30             -- brown out voltage
pragma target WDT           CONTROL         -- watchdog software controlled
pragma target WDTPS         P32K            -- watch dog scaler setting
pragma target MCLR          EXTERNAL        -- external reset
pragma target LVP           ENABLED         -- allow low-voltage programming
pragma target XINST         DISABLED         -- extended instruction set
pragma target DEBUG         DISABLED        -- background debugging
pragma target CP0           DISABLED        -- code block 0 not protected
pragma target CP1           DISABLED        -- code block 1 not protected
pragma target CPB           DISABLED        -- bootblock code not write protected
pragma target WRT0          DISABLED        -- table writeblock 0 not protected
pragma target WRT1          DISABLED        -- table write block 1 not protected
pragma target WRTB          DISABLED        -- bootblock not write protected
pragma target WRTC          DISABLED        -- config not write protected
pragma target EBTR0         DISABLED        -- table read block 0 not protected
pragma target EBTR1         DISABLED        -- table read block 1 not protected
pragma target EBTRB         DISABLED        -- boot block not protected
pragma target HFOFST        ENABLED         -- THE_SYSTEM_CLOCK_IS_HELD_OFF_UNTIL_THE_HFINTOSC_IS_STABLE

WDTCON_SWDTEN = OFF                          -- WDT off
;@jallib section led
-- LED IO definition
alias led             is pin_c4
alias led_direction   is pin_c4_direction
alias led2            is pin_c6
alias led2_direction  is pin_c6_direction

led_direction = output

if (defined(led2)) then -- compile only when led2 is defined.
   led2_direction = output
end if

-- set all IO as digital
enable_digital_io()

-- setup the timer0_isr_interval library
const word timer0_isr_rate = 1000  -- 1 kHz isr rate
const DELAY_SLOTS = 2         -- support 2 delays at the same time
include timer0_isr_interval
timer0_isr_init()             -- init timer0 isr

var word prev_interval_counter

   forever loop

      if (isr_counter != prev_interval_counter) then
         prev_interval_counter = isr_counter
         -- put here code that you want
         -- to execute each tick.
      end if ; 1 kHz loop

      if (check_delay(0)) then
         set_delay(0, 409) -- 409 ticks on delay-slot 0
         led = !led
      end if
      if (defined(led2)) then -- compile only when led2 is defined.
         if (check_delay(1)) then
            set_delay(1, 619) -- 619 ticks on delay-slot 1
            led2 = !led2
         end if
      end if
   end loop

; end of main

Generated by JALlib CHM Help System | Source: timer0_isr_interval.jal


timer0_isr_interval.jal - JALLIB Library Documentation

timer0_isr_interval.jal JALLIB LIBRARY

Title

timer0 isr interval

Author

Joep Suijs, Copyright (C) 2008..2022 Joep Suijs, Adapted-by: Rob Hamerling, Rob Jansen

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Fixed interval isr with support for non-blocking delays.
.
The setup of this library is straight-forward. First you define the interval
of the interrupt you want. With a higher value, more interrupts are generated.
This gives a higher resolution of your delay, but also puts a high background
load on your PIC. Be carefull if you go beyond 1000 (1kHz). The lowest possible
rate depends on the clock frequency you use and is 77 with an 16f877 on 20 MHz.
.
const TIMER0_ISR_RATE = 1000 -- 1 kHz isr rate
.
Next, you need to specify the number of slots. A slot is used to store the
end-time of a delay-period so you need one slot for each concurrent delay.
.
const DELAY_SLOTS = 2 -- support 2 delays at the same time
.
Now, include the library and call its init function:
.
include timer0_isr_interval
timer0_isr_init() -- init timer0 isr
.
Now we are ready to use the delay functions. To demonstrate its use, we take
two LEDs and let them blink at their own interval:
.
forever loop
if (check_delay(0)) then
set_delay(0, 409) -- 409 ticks on delay-slot 0
led = !led
end if
if (check_delay(1)) then
set_delay(1, 619) -- 619 ticks on delay-slot 1
led2 = !led2
end if
end loop
TODO:

Aliases for compatibilty with other PICs.

Constants and Variables

internal_isr_counter - var word
timer0_load - var byte

Routines

  • ISR - Procedure
  • check_delay - Function returns bit
  • isr_counter'get - Function returns word
  • set_delay - Procedure
  • timer0_isr_init - Procedure


timer0_poll_init - JALlib Procedures Help

timer0_poll_init JALLIB PROCEDURE

Signature

procedure timer0_poll_init() is

Description

initialize the timer and related variables.
automatically detects and makes use of 16-bit
timer0 if present.

Include

To use this procedure, include the library:

include timer0_poll_interval

Parameters

None

Return Value

None

Example

From sample file: 18f2520_tmr0_poll_interval.jal

-- Title: test timer0 interval w/ polling
--
-- Author: William Welch, Copyright (c) 2008-2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: test the library timer0_poll_interval
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2520_js.jal
--    * test : test_tmr0_poll_interval.jal
--

;@jallib section chipdef
-- chip setup
include 18f2520

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                      -- allow LVP
pragma target  WDT CONTROL                      -- watchdog software controlled

WDTCON_SWDTEN = OFF                             -- disable watchdog
;@jallib section led
-- LED IO definition
alias led             is pin_c5
alias led_direction   is pin_c5_direction

led_direction = output

if (defined(led2)) then -- compile only when led2 is defined.
   led2_direction = output
end if

-- set all IO as digital
enable_digital_io()

-- setup the timer0_poll_interval library
const timer0_overflow_rate = 1000  -- 1 kHz overflow rate
const DELAY_SLOTS = 2         -- support 2 delays at the same time
include timer0_poll_interval
timer0_poll_init()             -- init timer0

var word prev_interval_counter

forever loop

   if (timer0_interval_counter != prev_interval_counter) then
      prev_interval_counter = timer0_interval_counter
      -- put here code that you want
      -- to execute each tick.
   end if ; 1 kHz loop

   if (check_delay(0)) then
      set_delay(0, 409) -- 409 ticks on delay-slot 0
      led = !led
   end if
      if (defined(led2)) then -- compile only when led2 is defined.
   if (check_delay(1)) then
      set_delay(1, 619) -- 619 ticks on delay-slot 1
        led2 = !led2
      end if
   end if
end loop

; end of main

Generated by JALlib CHM Help System | Source: timer0_poll_interval.jal


timer0_poll_interval.jal - JALLIB Library Documentation

timer0_poll_interval.jal JALLIB LIBRARY

Title

timer0 poll interval

Author

Joep Suijs, Copyright (C) 2008 Joep Suijs, Adapted-by: Rob Hamerling, William Welch

Compiler

>=2.4m

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Fixed interval support for non-blocking delays, but without using
an interrupt.
.
Note: In many (possibly most) cases, you would be wise to choose the ISR
version of this library-- it will be much more accurate.
.
The setup of this library is straight-forward. First you define the overflow
rate for the timer. You'll have to make some trade-offs as to accuracy, frequency
of polling, etc.
.
>>> const timer0_overflow_rate = 1000 -- 1 kHz overflow rate
.
Optional usage, for finer control, you may specify:
.
>>> const timer0_preload_value = nnn ( 0-0xff (8-bit), or 0-0xffff (16-bit) )
>>> const timer0_prescale_value = nnn (0-7)
.
Next, you need to specify the number of slots. A slot is used to store the
end-time of a delay-period so you need one slot for each concurrent delay.
.
>>> const DELAY_SLOTS = 2 -- support 2 delays at the same time
.
Now, include the library and call it's init function:
.
>>> include timer0_poll_interval
>>> timer0_poll_init() -- init timer0
.
Now we are ready to use the delay functions. To demonstrate it's use, we take
two LEDs and let them blink at their own interval:
.
>> forever loop
>> if (check_delay(0)) then
>> set_delay(0, 409) -- 409 ticks on delay-slot 0
>> led = !led
>> end if
>> if (check_delay(1)) then
>> set_delay(1, 619) -- 619 ticks on delay-slot 1
>> led2 = !led2
>> end if
>> end loop

Constants and Variables

timer0_interval_counter - var word
timer0_load - var word

Routines

  • _timer0_poll - Procedure
  • _timer0_poll_init_rate - Procedure
  • check_delay - Function returns bit
  • interval_counter'get - Function returns word
  • set_delay - Procedure
  • timer0_poll_init - Procedure


timer1.jal - JALLIB Library Documentation

timer1.jal JALLIB LIBRARY

Title

Timer library (Timer Alias for timer 0)

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Provides a standard way to use timers.

Constants and Variables

TIMER1_IS_BITS - const byte = 16
TIMER1_IS_BITS - const byte = 8
TIMER1_IS_BITS - const byte = 8

Routines

  • timer_init - Procedure


timer3.jal - JALLIB Library Documentation

timer3.jal JALLIB LIBRARY

Title

Timer library (Timer Alias for timer 0)

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Provides a standard way to use timers.

Constants and Variables

TIMER3_IS_BITS - const byte = 16
TIMER3_IS_BITS - const byte = 8
TIMER3_IS_BITS - const byte = 8

Routines

  • timer_init - Procedure


timer_frequency.jal - JALLIB Library Documentation

timer_frequency.jal JALLIB LIBRARY

Title

Timer Frequency library

Author

Matthew Schinkel, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Provides a procedure to easily set a timer interval
for a given frequrency.

Notes

------------------------------------------------------------------------
returns timer interval required for a desired frequency
return value of 0 indicates the desired frequency can't be calculated.
freq_hz - your desired frequency
freq_adjust - adjust by number of timer steps
(may want to use OSCCAL reg instead)
------------------------------------------------------------------------

Routines

  • timer_freq - Function returns word


timer_init - JALlib Procedures Help

timer_init JALLIB PROCEDURE

Signature

procedure timer_init() is

Description

Initialize timer and start timer
with interrupts enabled.

Include

To use this procedure, include the library:

include timer0

Parameters

None

Return Value

None

Example

From sample file: 18f4620_timer.jal

-- Title: Basic usage of timer library
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q5
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This example shows basic usage of timer library for a
--              standard way to use timers. This sample outputs a 1khz
--              square wave, while blinking a led.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- notes:
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS                        -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O

-- timer out def
alias wave_out             is pin_a1
alias wave_out_direction   is pin_a1_direction
--
wave_out_direction = output

-- led def
alias led             is pin_a0
alias led_direction   is pin_a0_direction
--
led_direction = output

-- Setup timer Lib
const byte TIMER0_PS_RATIO = 1              -- set prescaller ratio
const byte TIMER0_BITS = 16                 -- Use 8 or 16 bits
const byte TIMER0_ENABLE_INTERRUPT = TRUE   -- Interrupts off/on
include timer0
timer_init()                                -- configures and starts timer
-- Other config:
timer0_cs = 0                               -- 0 = internal, 1 = external

-- Alias the timer to allow this sample to use timer0
alias timer          is timer0              -- the timer/counter
alias TIMER_PS_RATIO is TIMER0_PS_RATIO     -- prescaller ratio
alias TIMER_BITS     is TIMER0_BITS         -- timer bits
alias timer_cs       is timer0_cs           -- timer clock select
alias timer_if       is timer0_if           -- timer interrupt occurred bit

--------------------------------------------------------------------------
-- returns timer interval required for a desired frequency
-- return value of 0 indicates the desired frequency can't be calculated.
-- freq_hz     - your desired frequency
-- freq_adjust - adjust by number of timer steps (may want to use OSCCAL reg.)
--------------------------------------------------------------------------
function calc_freq(dword in freq_hz, sword in freq_adjust) return word is
   var dword timer_interval

   -- Timer rollover value - 65535 for 16 bit timer, 255 for 8 bit.
   var bit*TIMER_BITS timer_rollover = 0
   timer_rollover = timer_rollover - 1

   var dword value1 = (1000000000/freq_hz)/2                    ;5000
   var dword value2 = (1000/(target_clock/1000000))*4           ;100

   if (value2 > value1) then
      return 0
   else
      if timer_rollover > (value1 / value2) then ;Check if the timer can wait this long
         timer_interval = timer_rollover - (value1 / value2)

         if (value1 / value2) < 50 then ;Allow enough time for the IRS to complete
            return 0
         else
            return word(timer_interval + freq_adjust)
         end if
      else
          return 0
      end if
   end if
end function

-- Set this to desired interval. timer3 will count up.
-- Interupt will occur when timer_interval rolls
-- over from 65535 to 0
;var word timer_interval = 65535 - 2500 -- 63035 = 1khz square wave at 20mhz,
var word timer_interval = calc_freq(1000,0) -- same result as previous line at 20mhz
--
-- output will change every 0.5ms, full wave in 1ms.
-- interrupt occurs every 0.5ms
-- this value can be calculated:
-- 65535    - ( (1/1khz/2) / ( (1/20_000_000)*4 ) ) = 63035
-- timermax - ( (1/HZ/2) / ( (1/OSC FREQ  )*4 ) ) = timer_interval

-- Turn off timer if timer can't be set to the correct freq.
-- Try 16 bit timer.
-- If it's not working with your settings, you may need prescaler
if timer_interval == 0 then
   ;timer_on = 0  -- uncomment
end if

-----------
procedure timer_isr() is
   pragma interrupt          -- interupt procedure

   if !timer_if then       -- check if this is a timer interupt
      return                 -- exit interupt if it is not
   end if

   timer_if = off          -- clear overflow to start timer

   wave_out = !wave_out      -- change wave_out pin to oposite value
   timer = timer_interval -- set the interval
end procedure

-- main program here
forever loop
   _usec_delay (250_000)
   led = on
   _usec_delay (250_000)
   led = off
end loop

Generated by JALlib CHM Help System | Source: timer0.jal


tm1637.jal - JALLIB Library Documentation

tm1637.jal JALLIB LIBRARY

Title

Library for the TM1637 LED drive control special circuit.

Author

Rob Jansen, Copyright (c) 2020..2022, all rights reserved., Adapted-by:

Compiler

2.5r6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Libray for use of the TM1637 LED drive control special circuit.
It provides functions to write data to the LED displays and a
function to read the keyboard.

Notes

The following pins must be defined by the main program before
including this library:
-) alias tm1637_clk -- To CLK of the TM1637
-) alias tm1637_clk_direction
-) alias tm1637_dio -- To DIO of the TM1637
-) alias tm1637_dio_direction
Note that modules with 7-segement displays often have capacitors on
the clk and dio line. These should be removed.
The default number of displays is 6 which can be overruled by
defining the constant TM1637_WIDTH with a value of 1 .. 6.
Depending on the module used, the display order can be different.
This can be set by defining an array TM1637_DISPLAY_ORDER where
the rightmost display has number 0 and the leftmost display has
number TM1637_WIDTH - 1.
-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------

Display constants. We assume 6 displays unless defined otherwise.

Sources

Inspired by: https://github.com/avishorp/TM1637
Also see the TM1637 datasheet of Titan Micro Electronics

Constants and Variables

TM1637_WIDTH - const byte = 6
TM1637_MIN_BRIGHTNESS - const byte = 0
TM1637_MAX_BRIGHTNESS - const byte = 7
TM1637_SEGMENT_A - const byte = 0b0000_0001
TM1637_SEGMENT_B - const byte = 0b0000_0010
TM1637_SEGMENT_C - const byte = 0b0000_0100
TM1637_SEGMENT_D - const byte = 0b0000_1000
TM1637_SEGMENT_E - const byte = 0b0001_0000
TM1637_SEGMENT_F - const byte = 0b0010_0000
TM1637_SEGMENT_G - const byte = 0b0100_0000
TM1637_SEGMENT_DP - const byte = 0b1000_0000
TM1637_SEGMENT_OFF - const byte = 0b0000_0000
TM1637_SEGMENT_ALL - const byte = 0b1111_1111
TM1637_SEGMENT_MIN - const byte = 0b0100_0000
TM1637_NO_KEY - const byte = 0
TM1637_MIN_KEY - const byte = 1
TM1637_MAX_KEY - const byte = 16
quotient - var dword
minus_position - var byte

Routines

  • _tm1637_acknowlege_transmission - Procedure
  • _tm1637_read_byte - Function returns byte
  • _tm1637_start_transmission - Procedure
  • _tm1637_stop_transmission - Procedure
  • _tm1637_write_byte - Procedure
  • _tm1673_clock_delay - Procedure
  • tm1637_digit_to_segment - Function returns byte
  • tm1637_display_byte_dec - Procedure
  • tm1637_display_byte_hex - Procedure
  • tm1637_display_clear - Procedure
  • tm1637_display_dword_dec - Procedure
  • tm1637_display_nibble_hex - Procedure
  • tm1637_display_off - Procedure
  • tm1637_display_on - Procedure
  • tm1637_display_sdword_dec - Procedure
  • tm1637_display_update - Procedure
  • tm1637_display_word_dec - Procedure
  • tm1637_display_word_hex - Procedure
  • tm1637_init - Procedure
  • tm1637_scan_key - Function returns byte
  • tm1637_set_brightness - Procedure
  • tm1637_set_display - Procedure
  • tm1637_set_dot - Procedure


tm1637_digit_to_segment - JALlib Procedures Help

tm1637_digit_to_segment JALLIB FUNCTION

Signature

function tm1637_digit_to_segment(byte in value) return byte is

Description

Encode the given digit to the correct display segments.

Include

To use this procedure, include the library:

include tm1637

Parameters

  • value - byte in

Return Value

byte - Function return value

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_byte_dec - JALlib Procedures Help

tm1637_display_byte_dec JALLIB PROCEDURE

Signature

procedure tm1637_display_byte_dec(byte in number, byte in display_offset,

Description

Display a byte in decimal format where the least significant digit is written
at the location of 'display_offset' which is the number op positions from the right.
If 'leading_zeros' is TRUE then '0' are written in front of the number.
When 0 is given as number, nothing is displayed unless 'leading_zeros' is set,
then only one 0 is displayed.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_byte_hex - JALlib Procedures Help

tm1637_display_byte_hex JALLIB PROCEDURE

Signature

procedure tm1637_display_byte_hex(byte in value, byte in display_number) is

Description

Display a hexadecimal byte on a specific display. The display_number must
be in range 0 (most right) to TM1637_WIDTH - 2 (most left)

Include

To use this procedure, include the library:

include tm1637

Parameters

  • value - byte in
  • display_number - byte in

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_clear - JALlib Procedures Help

tm1637_display_clear JALLIB PROCEDURE

Signature

procedure tm1637_display_clear() is

Description

Switch all segments off.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_dword_dec - JALlib Procedures Help

tm1637_display_dword_dec JALLIB PROCEDURE

Signature

procedure tm1637_display_dword_dec(dword in number, byte in display_offset,

Description

Display a dword in decimal format where the least significant digit is written
at the location of 'display_offset' which is the number of positions from the right.
If 'leading_zeros' is TRUE then '0' are written in front of the number.
Number is limited to 999999 when using 6 displays. When 0 is given as number,
nothing is displayed unless 'leading_zeros' is set, then only one 0 is displayed.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_nibble_hex - JALlib Procedures Help

tm1637_display_nibble_hex JALLIB PROCEDURE

Signature

procedure tm1637_display_nibble_hex(byte in value, byte in display_number) is

Description

Display a hexadecimal nibble on a specific display. The display_number must
be in range 0 (most right) to TM1637_WIDTH - 1 (most left)

Include

To use this procedure, include the library:

include tm1637

Parameters

  • value - byte in
  • display_number - byte in

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_off - JALlib Procedures Help

tm1637_display_off JALLIB PROCEDURE

Signature

procedure tm1637_display_off() is

Description

Turn all displays off.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_on - JALlib Procedures Help

tm1637_display_on JALLIB PROCEDURE

Signature

procedure tm1637_display_on() is

Description

Turn all displays on.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_sdword_dec - JALlib Procedures Help

tm1637_display_sdword_dec JALLIB PROCEDURE

Signature

procedure tm1637_display_sdword_dec(sdword in number, byte in display_offset,

Description

Display a sdword in decimal format where the least significant digit is written
at the location of 'display_offset' which is the number of positions from the right.
If 'leading_zeros' is TRUE then '0' are written in front of the number.
Number is limited to -99999 when using 6 displays.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_update - JALlib Procedures Help

tm1637_display_update JALLIB PROCEDURE

Signature

procedure tm1637_display_update() is

Description

Send the data stored in the global array tm1637_display_data to the displays.
The order in which the data from tm1637_display_data is written is defined by
TM1637_DISPLAY_ORDER. This function only needs to be called by the user when
the user writes data directly into the global display data buffer.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_display_word_hex - JALlib Procedures Help

tm1637_display_word_hex JALLIB PROCEDURE

Signature

procedure tm1637_display_word_hex(word in value, byte in display_number) is

Description

Display a hexadecimal word on a specific display. The display_number must
be in range 0 (most right) to TM1637_WIDTH - 4 (most left)

Include

To use this procedure, include the library:

include tm1637

Parameters

  • value - word in
  • display_number - byte in

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_init - JALlib Procedures Help

tm1637_init JALLIB PROCEDURE

Signature

procedure tm1637_init() is

Description

Initialize and clear the display. The display is on but all segments are off.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_scan_key - JALlib Procedures Help

tm1637_scan_key JALLIB FUNCTION

Signature

function tm1637_scan_key() return byte is

Description

Check if a key was pressed and if so return the key number. The number is
between TM1637_MIN_KEY and TM1637_MAX_KEY or TM1637_NO_KEY if no key was
pressed.

Include

To use this procedure, include the library:

include tm1637

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_set_brightness - JALlib Procedures Help

tm1637_set_brightness JALLIB PROCEDURE

Signature

procedure tm1637_set_brightness(byte in brightness) is

Description

Set the brightness of the displays. Brightness is in range 0..7.

Include

To use this procedure, include the library:

include tm1637

Parameters

  • brightness - byte in

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_set_display - JALlib Procedures Help

tm1637_set_display JALLIB PROCEDURE

Signature

procedure tm1637_set_display(byte in segment_data, byte in display_number) is

Description

Set the segments for the given display with the given segment data.
Note: Use function tm1637_digit_to_segment() to translate a digit (0..F) to
the correct segment value for the display.
A segment data of TM1637_SEGMENT_OFF will clear all segments of that display.
Display number must be in range 0 (most right) to TM1637_WIDTH - 1 (most left)

Include

To use this procedure, include the library:

include tm1637

Parameters

  • segment_data - byte in
  • display_number - byte in

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1637_set_dot - JALlib Procedures Help

tm1637_set_dot JALLIB PROCEDURE

Signature

procedure tm1637_set_dot(bit in dot_on, byte in display_number) is

Description

Set or clear the dot of the given display determined by the dot value.
A value of 'dot_on' TRUE will turn the dot on, FALSE will turn it off.
Display number must be in range 0 (most right) to TM1637_WIDTH - 1 (most left)

Include

To use this procedure, include the library:

include tm1637

Parameters

  • dot_on - bit in
  • display_number - byte in

Return Value

None

Example

From sample file: 16f1823_tm1637_6_displays_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: Sample program for the TM1637 with six 7-segment displays and keyboard.
-- Author: Rob Jansen, Copyright (c) 2020..2022 all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r6
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Shows all features of the TM1637 library for the display
--              display functionality as well as the keyboard functionality.
--              The default number of displays is 6 which can be overruled by
--              defining the constant TM1637_WIDTH with a value of 1 .. 6.
--
-- Sources: Data sheet TM1637 from Titan Micro Electronics, V2.4.
--
-- Notes:   The following pins must be defined by the main program before
--          including the library:
--          -) alias tm1637_clk            -- To CLK of the TM1637
--          -) alias tm1637_clk_direction
--          -) alias tm1637_dio            -- To DIO of the TM1637
--          -) alias tm1637_dio_direction
--          Note that modules with 7-segement displays often have capacitors on
--          the clk and dio line. These should be removed.
--
--          The default number of displays is 6 which can be overruled by
--          defining the constant TM1637_WIDTH with a value of 1 .. 6.
--          Depending on the module used, the display order can be different.
--          This can be set by defining an array TM1637_DISPLAY_ORDER where
--          the rightmost display has number 0 and the leftmost display has
--          number TM1637_WIDTH - 1.
--
--
include 16f1823

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

-- Enable weak pull up for all ports.
WPUA = 0b0011_1111
WPUC = 0b0011_1111
OPTION_REG_WPUEN = FALSE

enable_digital_io()

-- TM1637 pin definition.
alias tm1637_clk is pin_C0 -- Pin 10 for 14 pin DIP
alias tm1637_clk_direction is pin_C0_direction
alias tm1637_dio is pin_C1 -- Pin 9 for 14 pin DIP.
alias tm1637_dio_direction is pin_C1_direction

-- You can change the display width (default is 6 when not defined).
; const byte TM1637_WIDTH = 4
-- Set the display order, rightmost is 0, leftmost is TM1637_WIDTH - 1.
; const byte TM1637_DISPLAY_ORDER[TM1637_WIDTH] = {3,2,1,0}

include tm1637
tm1637_init()

--- Display 'hELLo ' on the display.
const byte DISPLAY_HELLO[TM1637_WIDTH] =
             {
             0b1000_0000, -- decimal point
             0b0101_1100, -- o
             0b0011_1000, -- L
             0b0011_1000, -- L
             0b0111_1001, -- E
             0b0111_0100  -- h
             }

-- Wait for some time.
procedure wait_long() is
   _usec_delay(5_000_000)
end procedure

procedure wait_short() is
   _usec_delay(500_000)
end procedure

-- Check if a key is pressed. If so display it and wait for key release.
procedure do_key() is

   var byte key

   -- Check if a key was present and display it as ' NR   ' where NR is the
   -- key number that has been pressed.
   key = tm1637_scan_key()
   if (key != TM1637_NO_KEY) then
      tm1637_display_clear()
      tm1637_display_byte_dec(key,3,FALSE)
   end if
   while (tm1637_scan_key() != TM1637_NO_KEY) loop
      -- Wait for key release.
   end loop

end procedure

var sdword big_pos_counter
var sdword big_neg_counter
var word word_counter
var byte counter

forever loop

   -- Write a 'hELLo ' message by writing the segment data directly into the
   -- global display data buffer.
   for TM1637_WIDTH using counter loop
      tm1637_display_data[counter] = DISPLAY_HELLO[counter]
   end loop
   -- We need to update the display with this segment data.
   tm1637_display_update()
   wait_long()

   -- Switch display off for some time
   tm1637_display_off()
   wait_short()
   tm1637_display_on()

   -- Change the brightness.
   for (TM1637_MAX_BRIGHTNESS + 1) using counter loop
      tm1637_set_brightness(counter)
      wait_short()
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Now clear the display, that is all segments are off.
   tm1637_display_clear()
   wait_short()

   -- Set the dots on and off.
   for TM1637_WIDTH using counter loop
      tm1637_set_dot(TRUE, counter)
      wait_short()
      tm1637_set_dot(FALSE, counter)
    end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Set an individual display and show its number.
   tm1637_display_clear()
   for TM1637_WIDTH using counter loop
      tm1637_set_display(tm1637_digit_to_segment(counter), counter)
      wait_short()
      tm1637_set_display(TM1637_SEGMENT_OFF,counter)
   end loop

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal nibble on the rightmost display.
   tm1637_display_clear()
   for 16 using counter loop
      tm1637_display_nibble_hex(counter,0)
      _usec_delay(200_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal byte on the rightmost display.
   tm1637_display_clear()
   for 256 using counter loop
      tm1637_display_byte_hex(counter,0)
      _usec_delay(10_000)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Write a hexdecimal word on the rightmost display.
   tm1637_display_clear()
   for 512 using word_counter loop
      tm1637_display_word_hex(word_counter,0)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way with leading zero's.
   tm1637_display_clear()
   for 2021 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),0,TRUE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a counter in another way without leading zero's, skipping 3 positions.
   tm1637_display_clear()
   for 1_000 using big_pos_counter loop
      tm1637_display_dword_dec(dword(big_pos_counter),3,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

   -- Show a negative counter in another way without leading zero's.
   tm1637_display_clear()
   for 2023 using big_pos_counter loop -- Up and until the year 2022 :-)
      big_neg_counter = -big_pos_counter
      tm1637_display_sdword_dec(big_neg_counter,0,FALSE)
   end loop
   wait_short()

   -- Check if a key was pressed and if so show its number on the display.
   do_key()

end loop

Generated by JALlib CHM Help System | Source: tm1637.jal


tm1638.jal - JALLIB Library Documentation

tm1638.jal JALLIB LIBRARY

Title

Library to support 7-segment display module with TM1638

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for a module with TM1638 with
- serial interface
- 8 7-segment displays with dp (decimal point)
- 8 LEDs
- 8 push buttons
.
Data may be displayed anywhere in the 7-segment displays.
The position may be specified with an offset (depending on data type)
.
The tm1638 module uses 3 data wires, which have to be specified by the user.
Before including this library declare the following aliases (mandatory):
.
alias tm1638_dio is pin_?? -- pin for data I/O signal
alias tm1638_clk is pin_?? -- pin for clock signal
alias tm1638_stb is pin_?? -- pin for chip select signal
alias tm1638_dio_direction is pin_??_direction
.
The pins for tm1638_clk and tm1638_stb must be configured
for digital output by the user program
.
The following constant may be specified as well (optionally):
.
const byte TM1638_WIDTH = ? (number of 7-segment digits, defaults to 8)
.
Initialize the TM1638 with tm1638_init()
Dependencies: tm1638_font.jal

Notes

- Supports (= has been tested) only a module with tm1638 chip and
8 display digits, 8 single color LEDs and 8 buttons.
Support for modules with duo-leds or TM1640 may be added later.
-----------------------------------------------------------------------------

Constants and Variables

TM1638_LED_OFF - const byte = 0b_0000_0000 --
TM1638_LED_ON - const byte = 0b_0000_0001 --
TM1638_WRITE_DATA - const byte = 0b_0100_0000 --
TM1638_READ_KEYS - const byte = 0b_0100_0010 --
TM1638_ADDRESS_AUTO - const byte = 0b_0100_0000 --
TM1638_ADDRESS_FIXED - const byte = 0b_0100_0100 --
TM1638_MODE_NORMAL - const byte = 0b_0100_0000 --
TM1638_MODE_TEST - const byte = 0b_0100_1000 --
TM1638_DISPLAY_ON - const byte = 0b_1000_1000
TM1638_DISPLAY_OFF - const byte = 0b_1000_0000
TM1638_DISPLAY_PWM1 - const byte = 0b_1000_0000 --
TM1638_DISPLAY_PWM2 - const byte = 0b_1000_0001 --
TM1638_DISPLAY_PWM4 - const byte = 0b_1000_0010 --
TM1638_DISPLAY_PWM10 - const byte = 0b_1000_0011 --
TM1638_DISPLAY_PWM11 - const byte = 0b_1000_0100 -- PWM dutycycle for LEDs
PWM dutycycle for LEDs
TM1638_DISPLAY_PWM12 - const byte = 0b_1000_0101 --
TM1638_DISPLAY_PWM13 - const byte = 0b_1000_0110 --
TM1638_DISPLAY_PWM14 - const byte = 0b_1000_0111 --
TM1638_ADDRESS_SELECT - const byte = 0b_1100_0000 -- base of command byte
base of command byte
TM1638_DOT - const byte = 0b_1000_0000 -- segment of decimal point
segment of decimal point
TM1638_WIDTH - const byte = 8 -- default number of digits in display
default number of digits in display
mode - var byte = TM1638_DISPLAY_OFF -- default state OFF
default state OFF
i - var byte
tbyte - var byte = _TM1638_NUMBER_FONT[digit & 0x0f]
i - var byte
i - var byte
quot10 - var dword = number / 10
rem10 - var byte = byte(number % 10)
tbyte - var byte = _TM1638_MINUS

Routines

  • _tm1638_read_byte - Function returns byte
  • _tm1638_write_byte - Procedure
  • _tm1638_write_command - Procedure
  • _tm1638_write_data_at - Procedure
  • tm1638_display_byte_bin - Procedure
  • tm1638_display_char - Procedure
  • tm1638_display_clear - Procedure
  • tm1638_display_digit - Procedure
  • tm1638_display_dword_dec - Procedure
  • tm1638_display_dword_hex - Procedure
  • tm1638_display_mode - Procedure
  • tm1638_display_sdword_dec - Procedure
  • tm1638_display_string - Procedure
  • tm1638_display_word_dec - Procedure
  • tm1638_get_buttons - Function returns byte
  • tm1638_init - Procedure
  • tm1638_set_led - Procedure
  • tm1638_set_leds - Procedure


tm1638_display_byte_bin - JALlib Procedures Help

tm1638_display_byte_bin JALLIB PROCEDURE

Signature

procedure tm1638_display_byte_bin(byte in number) is

Description

Title: Display binary number (byte, 8 bits)
Input: - byte with value to be displayed

Include

To use this procedure, include the library:

include tm1638

Parameters

  • number - byte in

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_char - JALlib Procedures Help

tm1638_display_char JALLIB PROCEDURE

Signature

procedure tm1638_display_char(byte in data,

Description

Title: Display a character at a specified position
Input: - Index of the display position (0 = leftmost, 7 = rightmost)
- Byte with character to be displayed (ASCII value, range 32..127)
Notes: - Decimal point not supported

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_clear - JALlib Procedures Help

tm1638_display_clear JALLIB PROCEDURE

Signature

procedure tm1638_display_clear() is

Description

Title: Clear all display digits (inclusive decimal point)
Input: None

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_digit - JALlib Procedures Help

tm1638_display_digit JALLIB PROCEDURE

Signature

procedure tm1638_display_digit(byte in digit,

Description

Title: Display a (hexa)decimal digit on a specified position
Input: - byte with digit (binary value)
- byte with position (index, most left = 0)
- flag for decimal point (FALSE = no, TRUE = yes)
Notes:

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_dword_dec - JALlib Procedures Help

tm1638_display_dword_dec JALLIB PROCEDURE

Signature

procedure tm1638_display_dword_dec(dword in number,

Description

Title: Display an unsigned decimal number (dword) at a specific position
Input: - unsigned doubleword with value to be displayed
- byte with pattern of desired decimal points
- byte with offset: offset of least significant digit
- bit flag for leading zeroes (FALSE = no, TRUE = yes)
Notes: - Number is limited to 99999999
- offset is number of display positions from the right
- when number does not fit high order digits will be truncated.

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_dword_hex - JALlib Procedures Help

tm1638_display_dword_hex JALLIB PROCEDURE

Signature

procedure tm1638_display_dword_hex(dword in number,

Description

Title: Display a hexadecimal number (8 digits, right aligned)
Input: - doubleword with value to be displayed
- bit flag for leading zeroes (FALSE = no, TRUE = yes)
Notes: - Uses full display, no decimal points

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_mode - JALlib Procedures Help

tm1638_display_mode JALLIB PROCEDURE

Signature

procedure tm1638_display_mode(bit in active,

Description

Title: Control display mode of the TM1638
Input: - active (1) or inactive (0)
- LED intensity (range 0..7)
Notes: Can be used to change mode during operation

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_sdword_dec - JALlib Procedures Help

tm1638_display_sdword_dec JALLIB PROCEDURE

Signature

procedure tm1638_display_sdword_dec(sdword in number,

Description

Title: Display signed decimal number at a specific location
Input: - signed doubleword with value to be displayed
- byte with pattern of desired decimal points
- byte with offset: offset of least significant digit
- bit flag for leading zeroes (FALSE = no, TRUE = yes)
Notes: - negative numbers are limited to -9999999
- offset is number of display positions from the right!
- when number does not fit the high order digits are truncated.

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_string - JALlib Procedures Help

tm1638_display_string JALLIB PROCEDURE

Signature

procedure tm1638_display_string(byte in string[],

Description

Title: Display string (left to right) in 7-segment displays
Input: - index of first character of string on display (0..7, left to right)
- ASCII character string
Notes: - When string does not fit the rightmost characters are truncated

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_display_word_dec - JALlib Procedures Help

tm1638_display_word_dec JALLIB PROCEDURE

Signature

procedure tm1638_display_word_dec(word in number,

Description

Title: Display an unsigned decimal number (word)
Input: - unsigned word with value to be displayed
- byte with pattern of desired decimal points
- byte with offset of least significant digit (right to left)
- bit flag for leading zeroes (FALSE = no, TRUE = yes)

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_font.jal - JALLIB Library Documentation

tm1638_font.jal JALLIB LIBRARY

Title

Fonts for TM1638 library

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Fonts for TM1638
The bits are displayed by mapping below
-- 0 --
| |
5 1
-- 6 --
4 2
| |
-- 3 -- .7
Dependencies:
-----------------------------------------------------------------------------

definition for standard hexadecimal numbers


tm1638_get_buttons - JALlib Procedures Help

tm1638_get_buttons JALLIB FUNCTION

Signature

function tm1638_get_buttons() return byte is

Description

Title: Get button positions
Returns: Byte with bit pattern of buttons (0 = off, 1 = on)
Leftmost button (S1) is represented by the least significant bit.

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

byte - Byte with bit pattern of buttons (0 = off, 1 = on) Leftmost button (S1) is represented by the least significant bit.

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_init - JALlib Procedures Help

tm1638_init JALLIB PROCEDURE

Signature

procedure tm1638_init() is

Description

Title: Initialize TM1638 module
Notes: - The TM1638 module will be kept in fixed address mode,
only during init auto-increase mode is used (temporary).

Include

To use this procedure, include the library:

include tm1638

Parameters

None

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1638_set_leds - JALlib Procedures Help

tm1638_set_leds JALLIB PROCEDURE

Signature

procedure tm1638_set_leds(byte in leds) is

Description

Title: Set all LEDs
Input: Byte with bit pattern: 0 = off, 1 = on,
Leftmost led (LED1) is controlled by the least significant bit.
Returns: nothing

Include

To use this procedure, include the library:

include tm1638

Parameters

  • leds - byte in

Return Value

None

Example

From sample file: 16f648a_tm1638.jal

-- ------------------------------------------------------
-- Title: Test the TM1638 module
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1638 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of a PCB with
-- 8 7-segment displays, 8 LEDs and 8 push button switches.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_16f648a_js.jal
--    * test : test_tm1638.jal
--

;@jallib section chipdef
-- chip setup
include 16f648a

--
-- This program 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
pragma target LVP  enabled

--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1638 library
alias tm1638_dio            is pin_A0
alias tm1638_clk            is pin_A1
alias tm1638_stb            is pin_A2
alias tm1638_dio_direction  is pin_A0_direction

pin_A1_direction = OUTPUT
pin_A2_direction = OUTPUT

--
include tm1638                                  -- library for the TM1638
tm1638_init()                                   -- initalize the TM1638
--
var byte buttons                                -- bit pattern of the 8 push buttons
var byte leds                                   -- bit pattern of the 8 LEDs
var byte i

forever loop
   tm1638_display_mode(1, 2)                    -- set display on with low brightness
   buttons = tm1638_get_buttons()
   while buttons != 0 loop                      -- when any button pushed
      tm1638_set_leds(buttons)                  -- show pattern in LEDs
      tm1638_display_byte_bin(buttons)          -- show pattern in display
      buttons = tm1638_get_buttons()
   end loop                                     -- leaves LED of last pushed button
   tm1638_display_clear()
   tm1638_display_char("t", 0)                  -- char: offset from left
   tm1638_display_char("m", 2)
   tm1638_display_char("1", 4)
   tm1638_display_char("6", 5)
   tm1638_display_char("3", 6)
   tm1638_display_char("8", 7)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 0)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_string("--1638--", 2)         -- string: offset from left, shows: --1638
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1638_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1638_display_digit(3, 5, FALSE)
   delay_100ms(3)
   tm1638_display_digit(8, 7, FALSE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_clear()
   tm1638_display_dword_hex(0x79abcDEF, 0)                     -- numerics: offset from right
   for 7 using i loop
      tm1638_display_mode(1, i)
      delay_100ms(5)
   end loop
   tm1638_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(1)
   tm1638_display_mode(0, 7)                                   -- display off ('high' density!)
   delay_1s(1)
   tm1638_display_mode(1, 2)                                   -- display on, low density
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_dword_dec(99999999, 0b_1000_0001, 0, TRUE)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-654321, 0b_0001_1000, 0, TRUE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-1, 0b_0000_0000, 0, FALSE);
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 0, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_1000, 1, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0100_0010, 2, true)
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 3, false)      -- left aligned
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 4, false)      -- shows: 2345
   delay_1s(2)
   tm1638_display_clear()
   tm1638_display_word_dec(12345, 0b_0000_0000, 5, false)      -- shows: 345
   delay_1s(2)
   tm1638_set_leds(0x5A)                                       -- shows: .*.**.*. of LEDs
   tm1638_display_byte_bin(0x5A)                               -- shows: 01011010 in display
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1638.jal


tm1640.jal - JALLIB Library Documentation

tm1640.jal JALLIB LIBRARY

Title

Library to support 7-segment display module with TM1640

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for a module with TM1640 with
- serial interface
- 16 7-segment displays with dp (decimal point)
.
Data may be displayed anywhere in the 7-segment displays.
The position may be specified with an offset (depending on data type)
.
The tm1640 module uses 2 data wires, which have to be specified by the user.
Before including this library declare the following aliases (mandatory):
.
alias tm1640_din is pin_?? -- pin for data I/O signal
alias tm1640_clk is pin_?? -- pin for clock signal
which should be set to OUTPUT by the user program
.
The following constant may be specified as well (optionally):
.
const byte TM1640_WIDTH = ? (number of 7-segment digits, defaults to 16)
.
Initialize the TM1640 with tm1640_init()
Dependencies: tm1638_font.jal

Notes

- Supports (= has been tested) with a module with tm1640 chip
and 16 7-segment display digits
-----------------------------------------------------------------------------

Constants and Variables

TM1640_WRITE_DATA - const byte = 0b_0100_0000 --
TM1640_ADDRESS_AUTO - const byte = 0b_0100_0000 --
TM1640_ADDRESS_FIXED - const byte = 0b_0100_0100 --
TM1640_MODE_NORMAL - const byte = 0b_0100_0000 --
TM1640_MODE_TEST - const byte = 0b_0100_1000 --
TM1640_DISPLAY_ON - const byte = 0b_1000_1000
TM1640_DISPLAY_OFF - const byte = 0b_1000_0000
TM1640_DISPLAY_PWM1 - const byte = 0b_1000_0000 --
TM1640_DISPLAY_PWM2 - const byte = 0b_1000_0001 --
TM1640_DISPLAY_PWM4 - const byte = 0b_1000_0010 --
TM1640_DISPLAY_PWM10 - const byte = 0b_1000_0011 --
TM1640_DISPLAY_PWM11 - const byte = 0b_1000_0100 -- PWM dutycycle for LEDs
PWM dutycycle for LEDs
TM1640_DISPLAY_PWM12 - const byte = 0b_1000_0101 --
TM1640_DISPLAY_PWM13 - const byte = 0b_1000_0110 --
TM1640_DISPLAY_PWM14 - const byte = 0b_1000_0111 --
TM1640_ADDRESS_SELECT - const byte = 0b_1100_0000 -- base of command byte
base of command byte
TM1640_DOT - const byte = 0b_1000_0000 -- segment of decimal point
segment of decimal point
TM1640_WIDTH - const byte = 16 -- default number of digits in display
default number of digits in display
mode - var byte = TM1640_DISPLAY_OFF -- default state OFF
default state OFF
i - var byte
tbyte - var byte = _TM1638_NUMBER_FONT[digit & 0x0f]
i - var byte
i - var byte
quot10 - var dword = number / 10
rem10 - var byte = byte(number % 10)
tbyte - var byte = _TM1638_MINUS
i - var byte

Routines

  • _tm1640_write_byte_raw - Procedure
  • _tm1640_write_command - Procedure
  • _tm1640_write_data_at - Procedure
  • tm1640_display_byte_bin - Procedure
  • tm1640_display_char - Procedure
  • tm1640_display_clear - Procedure
  • tm1640_display_digit - Procedure
  • tm1640_display_dword_dec - Procedure
  • tm1640_display_dword_hex - Procedure
  • tm1640_display_mode - Procedure
  • tm1640_display_sdword_dec - Procedure
  • tm1640_display_string - Procedure
  • tm1640_display_word_bin - Procedure
  • tm1640_display_word_dec - Procedure
  • tm1640_init - Procedure


tm1640_display_byte_bin - JALlib Procedures Help

tm1640_display_byte_bin JALLIB PROCEDURE

Signature

procedure tm1640_display_byte_bin(byte in number,

Description

Title: Display binary number (byte, 8 bits)
Input: - byte with value to be displayed
- byte with offset from the right

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_char - JALlib Procedures Help

tm1640_display_char JALLIB PROCEDURE

Signature

procedure tm1640_display_char(byte in data,

Description

Title: Display a character at a specified position
Input: - Index of the display position (0 = leftmost)
- Byte with character to be displayed (ASCII value, range 32..127)
Notes: - Decimal point not supported together with other character

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_clear - JALlib Procedures Help

tm1640_display_clear JALLIB PROCEDURE

Signature

procedure tm1640_display_clear() is

Description

Title: Clear all display digits (inclusive decimal point)
Input: (none)
Notes: - Set display into normal mode (disable test mode)
and set display into fixed address mode at return.

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_digit - JALlib Procedures Help

tm1640_display_digit JALLIB PROCEDURE

Signature

procedure tm1640_display_digit(byte in digit,

Description

Title: Display a (hexa)decimal digit on a specified position
Input: - byte with digit (binary value)
- byte with position (index, most left = 0)
- flag for decimal point (FALSE = no, TRUE = yes)
Notes:

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_dword_dec - JALlib Procedures Help

tm1640_display_dword_dec JALLIB PROCEDURE

Signature

procedure tm1640_display_dword_dec(dword in number,

Description

Title: Display an unsigned decimal number (dword) at a specific position
Input: - unsigned doubleword with value to be displayed
- byte with pattern of desired decimal points
- byte with offset: offset of least significant digit
- bit flag for leading zeroes (FALSE = no, TRUE = yes)
Notes: - offset is number of display positions from the right
- when number does not fit high order digits will be truncated.

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_dword_hex - JALlib Procedures Help

tm1640_display_dword_hex JALLIB PROCEDURE

Signature

procedure tm1640_display_dword_hex(dword in number,

Description

Title: Display a hexadecimal number (8 digits, right aligned)
Input: - doubleword with value to be displayed
- bit flag for leading zeroes (FALSE = no, TRUE = yes)
Notes: - No decimal points supported

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_mode - JALlib Procedures Help

tm1640_display_mode JALLIB PROCEDURE

Signature

procedure tm1640_display_mode(bit in active,

Description

Title: Control display mode of the TM1640
Input: - active (1) or inactive (0)
- LED intensity (range 0..7)

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_sdword_dec - JALlib Procedures Help

tm1640_display_sdword_dec JALLIB PROCEDURE

Signature

procedure tm1640_display_sdword_dec(sdword in number,

Description

Title: Display signed decimal number at a specific location
Input: - signed doubleword with value to be displayed
- byte with pattern of desired decimal points
- byte with offset: offset of least significant digit
- bit flag for leading zeroes (FALSE = no, TRUE = yes)
Notes: - negative numbers are limited to -9999999
- offset is number of display positions from the right!
- when number does not fit the high order digits are truncated.

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_string - JALlib Procedures Help

tm1640_display_string JALLIB PROCEDURE

Signature

procedure tm1640_display_string(byte in string[],

Description

Title: Display string (left to right) in 7-segment displays
Input: - index of first character of string on display (0 is leftmost)
- ASCII character string
Notes: - When string does not fit the rightmost characters are truncated

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_word_bin - JALlib Procedures Help

tm1640_display_word_bin JALLIB PROCEDURE

Signature

procedure tm1640_display_word_bin(word in number) is

Description

Title: Display binary number (word, 16 bits)
Input: word with value to be displayed

Include

To use this procedure, include the library:

include tm1640

Parameters

  • number - word in

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_display_word_dec - JALlib Procedures Help

tm1640_display_word_dec JALLIB PROCEDURE

Signature

procedure tm1640_display_word_dec(word in number,

Description

Title: Display an unsigned decimal number (word)
Input: - unsigned word with value to be displayed
- byte with pattern of desired decimal points
- byte with offset of least significant digit (right to left)
- bit flag for leading zeroes (FALSE = no, TRUE = yes)

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


tm1640_init - JALlib Procedures Help

tm1640_init JALLIB PROCEDURE

Signature

procedure tm1640_init() is

Description

Title: Initialize TM1640 module
Notes:

Include

To use this procedure, include the library:

include tm1640

Parameters

None

Return Value

None

Example

From sample file: 18f2450_tm1640.jal

-- ------------------------------------------------------
-- Title: Test a 7-segment module with TM1640 chip
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q2
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description:
-- Simple program to test the tm1640 library.
-- Most procedures and functions are called at least once,
-- with different arguments to show the capabilities of
-- a ready-built PCB with 16 7-segment displays.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2450_af.jal
--    * test : test_tm1640.jal
--

;@jallib section chipdef
-- chip setup
include 18f2450

-- even though the external crystal is 20 MHz, the configuration is such that
-- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set
-- target frequency to 48 MHz since pragma target CPUDIV is P1
pragma target clock       48_000_000

-- fuses
pragma target PLLDIV        P5          -- divide by 5 (20 MHz)
pragma target CPUDIV        P1          -- [primary oscillator src: /1][96 mhz pll src: /2]
pragma target USBDIV        P2          -- CLOCK_SRC_FROM_96MHZ_PLL_2
pragma target OSC           HS_PLL      -- hs + pll, usb hs
pragma target FCMEN         DISABLED
pragma target IESO          DISABLED
pragma target PWRTE         DISABLED    -- power up timer
pragma target VREGEN        ENABLED     -- USB voltage regulator
pragma target VOLTAGE       V21         -- brown out voltage
pragma target BROWNOUT      DISABLED    -- no brownout detection
pragma target WDTPS         P32K        -- watch dog scaler setting
pragma target WDT           CONTROL     -- watchdog software controlled
pragma target PBADEN        DIGITAL     -- digital input port<0..4>
pragma target LPT1OSC       LOW_POWER   -- low power timer 1
pragma target MCLR          INTERNAL    -- no master reset
pragma target STVR          DISABLED    -- reset on stack over/under flow
pragma target LVP           ENABLED     -- allow low-voltage programming
pragma target XINST         DISABLED     -- extended instruction set
pragma target DEBUG         DISABLED    -- background debugging
pragma target CP0           DISABLED    -- code block 0 not protected
pragma target CP1           DISABLED    -- code block 1 not protected
pragma target CPB           DISABLED    -- bootblock code not write protected
pragma target WRT0          DISABLED    -- table writeblock 0 not protected
pragma target WRT1          DISABLED    -- table write block 1 not protected
pragma target WRTB          DISABLED    -- bootblock not write protected
pragma target WRTC          DISABLED    -- config not write protected
pragma target EBTR0         DISABLED    -- table read block 0 not protected
pragma target EBTR1         DISABLED    -- table read block 1 not protected
pragma target EBTRB         DISABLED    -- boot block not protected

WDTCON_SWDTEN = OFF                     -- disable watchdog

enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures
--
-- ----------------------------------
-- setup for the tm1640 library
alias tm1640_din  is pin_A0
alias tm1640_clk  is pin_A1

pin_A0_direction = OUTPUT
pin_A1_direction = OUTPUT
--
include tm1640                      -- library for the TM1640
tm1640_init()                       -- initalize the TM1640
--
var byte i

forever loop

   tm1640_display_clear()
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)  -- set display on with medium brightness

   tm1640_display_char("t", 1)                  -- char: offset from left
   tm1640_display_char("m", 2)
   tm1640_display_char("1", 3)
   tm1640_display_char("6", 4)
   tm1640_display_char("4", 5)
   tm1640_display_char("0", 6)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_digit(1, 1, FALSE)            -- single digit: offset from left
   delay_100ms(3)
   tm1640_display_digit(6, 3, TRUE)
   delay_100ms(3)
   tm1640_display_digit(4, 5, FALSE)
   delay_100ms(3)
   tm1640_display_digit(0, 7, FALSE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_string("0123456789AB", 0)
   delay_1s(2)
   tm1640_display_string("abcdefgh", 0)
   delay_1s(2)
   tm1640_display_string("ABCDEFGH", 8)
   delay_1s(2)
   tm1640_display_dword_hex(0x88888888, FALSE)                 -- all segments on (no dp)
   delay_1s(2)
   tm1640_display_dword_dec(0xFFFFFFFF, 0, 0, TRUE)
   delay_1s(2)
   for 7 using i loop
      tm1640_display_mode(1, i)
      delay_100ms(8)
   end loop
   tm1640_display_mode(1, TM1640_DISPLAY_PWM10)                -- display on, medium density
   tm1640_display_clear()
   tm1640_display_dword_dec(1234567, 0, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_dword_dec(99999999, 0b_1100_1010_0101_0011, 0, TRUE)
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-654321, 0b_0010_1010, 0, TRUE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-1, 0b_0000_1010, 0, FALSE);
   delay_1s(2)
   tm1640_display_clear()
   tm1640_display_sdword_dec(-12345678, 0, 0, 0)               -- doesn't fit, shows: -2345678
   delay_1s(2)
   for 5 using i loop
      tm1640_display_clear()
      tm1640_display_word_dec(12345, 1<<i, i, true)
      delay_1s(2)
   end loop
   delay_1s(2)
   tm1640_display_byte_bin(0x5A, 0)                            -- shows: 01011010 in display
   delay_1s(2)
   tm1640_display_word_bin(0x9669)
   delay_1s(2)
end loop
--

Generated by JALlib CHM Help System | Source: tm1640.jal


transceiver_cc1101.jal - JALLIB Library Documentation

transceiver_cc1101.jal JALLIB LIBRARY

Title

cc1101 transceiver library

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This library provides functions the TI cc1101 receiver.
Working baud rates are 1.2khz, 100khz and 250khz at 433.92Mhz.
This device will also work in the 900mhz range.
Max device power is 10dBi

Notes

I am not an RF genius, do your own testing and check your RF laws before
using. Use SmartRF studio for other settings.

Sources

https://www.ccsinfo.com/forum/viewtopic.php?t=54957&postdays=0&postorder=asc&start=0

variables

Constants and Variables

CC1101_WRITE_BURST - const byte = 0x40
CC1101_READ_SINGLE - const byte = 0x80
CC1101_READ_BURST - const byte = 0xC0
cc1101_has_error - var byte = 0
CC1101_IOCFG2 - const byte = 0x00 -- GDO2 output pin configuration
GDO2 output pin configuration
CC1101_IOCFG1 - const byte = 0x01 -- GDO1 output pin configuration
GDO1 output pin configuration
CC1101_IOCFG0 - const byte = 0x02 -- GDO0 output pin configuration
GDO0 output pin configuration
CC1101_FIFOTHR - const byte = 0x03 -- RX FIFO and TX FIFO thresholds
RX FIFO and TX FIFO thresholds
CC1101_SYNC1 - const byte = 0x04 -- Sync word, high int8
Sync word, high int8
CC1101_SYNC0 - const byte = 0x05 -- Sync word, low int8
Sync word, low int8
CC1101_PKTLEN - const byte = 0x06 -- Packet length
Packet length
CC1101_PKTCTRL1 - const byte = 0x07 -- Packet automation control
Packet automation control
CC1101_PKTCTRL0 - const byte = 0x08 -- Packet automation control
Packet automation control
CC1101_ADDR - const byte = 0x09 -- Device address
Device address
CC1101_CHANNR - const byte = 0x0A -- Channel number
Channel number
CC1101_FSCTRL1 - const byte = 0x0B -- Frequency synthesizer control
Frequency synthesizer control
CC1101_FSCTRL0 - const byte = 0x0C -- Frequency synthesizer control
Frequency synthesizer control
CC1101_FREQ2 - const byte = 0x0D -- Frequency control word, high int8
Frequency control word, high int8
CC1101_FREQ1 - const byte = 0x0E -- Frequency control word, middle int8
Frequency control word, middle int8
CC1101_FREQ0 - const byte = 0x0F -- Frequency control word, low int8
Frequency control word, low int8
CC1101_MDMCFG4 - const byte = 0x10 -- Modem configuration
Modem configuration
CC1101_MDMCFG3 - const byte = 0x11 -- Modem configuration
Modem configuration
CC1101_MDMCFG2 - const byte = 0x12 -- Modem configuration
Modem configuration
CC1101_MDMCFG1 - const byte = 0x13 -- Modem configuration
Modem configuration
CC1101_MDMCFG0 - const byte = 0x14 -- Modem configuration
Modem configuration
CC1101_DEVIATN - const byte = 0x15 -- Modem deviation setting
Modem deviation setting
CC1101_MCSM2 - const byte = 0x16 -- Main Radio Control State Machine configuration
Main Radio Control State Machine configuration
CC1101_MCSM1 - const byte = 0x17 -- Main Radio Control State Machine configuration
Main Radio Control State Machine configuration
CC1101_MCSM0 - const byte = 0x18 -- Main Radio Control State Machine configuration
Main Radio Control State Machine configuration
CC1101_FOCCFG - const byte = 0x19 -- Frequency Offset Compensation configuration
Frequency Offset Compensation configuration
CC1101_BSCFG - const byte = 0x1A -- Bit Synchronization configuration
Bit Synchronization configuration
CC1101_AGCCTRL2 - const byte = 0x1B -- AGC control
AGC control
CC1101_AGCCTRL1 - const byte = 0x1C -- AGC control
AGC control
CC1101_AGCCTRL0 - const byte = 0x1D -- AGC control
AGC control
CC1101_WOREVT1 - const byte = 0x1E -- High int8 Event 0 timeout
High int8 Event 0 timeout
CC1101_WOREVT0 - const byte = 0x1F -- Low int8 Event 0 timeout
Low int8 Event 0 timeout
CC1101_WORCTRL - const byte = 0x20 -- Wake On Radio control
Wake On Radio control
CC1101_FREND1 - const byte = 0x21 -- Front end RX configuration
Front end RX configuration
CC1101_FREND0 - const byte = 0x22 -- Front end TX configuration
Front end TX configuration
CC1101_FSCAL3 - const byte = 0x23 -- Frequency synthesizer calibration
Frequency synthesizer calibration
CC1101_FSCAL2 - const byte = 0x24 -- Frequency synthesizer calibration
Frequency synthesizer calibration
CC1101_FSCAL1 - const byte = 0x25 -- Frequency synthesizer calibration
Frequency synthesizer calibration
CC1101_FSCAL0 - const byte = 0x26 -- Frequency synthesizer calibration
Frequency synthesizer calibration
CC1101_RCCTRL1 - const byte = 0x27 -- RC oscillator configuration
RC oscillator configuration
CC1101_RCCTRL0 - const byte = 0x28 -- RC oscillator configuration
RC oscillator configuration
CC1101_FSTEST - const byte = 0x29 -- Frequency synthesizer calibration control
Frequency synthesizer calibration control
CC1101_PTEST - const byte = 0x2A -- Production test
Production test
CC1101_AGCTEST - const byte = 0x2B -- AGC test
AGC test
CC1101_TEST2 - const byte = 0x2C -- Various test settings
Various test settings
CC1101_TEST1 - const byte = 0x2D -- Various test settings
Various test settings
CC1101_TEST0 - const byte = 0x2E -- Various test settings
Various test settings
CC1101_SRES - const byte = 0x30 -- Reset chip.
Reset chip.
CC1101_SFSTXON - const byte = 0x31 -- Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL = 1).
Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL = 1).
CC1101_SXOFF - const byte = 0x32 -- Turn off crystal oscillator.
Turn off crystal oscillator.
CC1101_SCAL - const byte = 0x33 -- Calibrate frequency synthesizer and turn it off
Calibrate frequency synthesizer and turn it off
CC1101_SRX - const byte = 0x34 -- Enable RX. Perform calibration first if coming from IDLE and
Enable RX. Perform calibration first if coming from IDLE and
CC1101_STX - const byte = 0x35 -- In IDLE state: Enable TX. Perform calibration first if
In IDLE state: Enable TX. Perform calibration first if
CC1101_SIDLE - const byte = 0x36 -- Exit RX / TX, turn off frequency synthesizer and exit
Exit RX / TX, turn off frequency synthesizer and exit
CC1101_SAFC - const byte = 0x37 -- Perform AFC adjustment of the frequency synthesizer
Perform AFC adjustment of the frequency synthesizer
CC1101_SWOR - const byte = 0x38 -- Start automatic RX polling sequence (Wake-on-Radio)
Start automatic RX polling sequence (Wake-on-Radio)
CC1101_SPWD - const byte = 0x39 -- Enter power down mode when CSn goes high.
Enter power down mode when CSn goes high.
CC1101_SFRX - const byte = 0x3A -- Flush the RX FIFO buffer.
Flush the RX FIFO buffer.
CC1101_SFTX - const byte = 0x3B -- Flush the TX FIFO buffer.
Flush the TX FIFO buffer.
CC1101_SWORRST - const byte = 0x3C -- Reset real time clock.
Reset real time clock.
CC1101_SNOP - const byte = 0x3D -- No operation. May be used to pad strobe commands to two
No operation. May be used to pad strobe commands to two
CC1101_PARTNUM - const byte = 0x30
CC1101_VERSION - const byte = 0x31
CC1101_FREQEST - const byte = 0x32
CC1101_LQI - const byte = 0x33
CC1101_RSSI - const byte = 0x34
CC1101_MARCSTATE - const byte = 0x35
CC1101_WORTIME1 - const byte = 0x36
CC1101_WORTIME0 - const byte = 0x37
CC1101_PKTSTATUS - const byte = 0x38
CC1101_VCO_VC_DAC - const byte = 0x39
CC1101_TXBYTES - const byte = 0x3A
CC1101_RXBYTES - const byte = 0x3B
CC1101_PATABLE - const byte = 0x3E
CC1101_TXFIFO - const byte = 0x3F
CC1101_RXFIFO - const byte = 0x3F

Routines

  • cc1101_config_433_92mhz_100kbaud - Procedure
  • cc1101_config_433_92mhz_250kbaud - Procedure
  • cc1101_config_433_92mhz__1_2kbaud - Procedure
  • cc1101_init - Procedure
  • cc1101_read_burst_register - Procedure
  • cc1101_read_register - Function returns byte
  • cc1101_read_status - Function returns byte
  • cc1101_receive_mode - Procedure
  • cc1101_receive_packet - Procedure
  • cc1101_send_packet - Procedure
  • cc1101_strobe - Procedure
  • cc1101_transmit_mode - Procedure
  • cc1101_tx_10dbi - Procedure
  • cc1101_write_burst_reg - Procedure
  • cc1101_write_register - Procedure


udp.jal - JALLIB Library Documentation

udp.jal JALLIB LIBRARY

Title

UDP (User Datagram Protocol) BETA

Author

Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved., Adapted-by:

Compiler

>=2.4n

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

An unreliable, connection less protocol, used to send and
recieve data. The application must provide it's own reliability.

Sources

http://www.networksorcery.com/enp/protocol/udp.htm
Note:

Constants and Variables

UDP_SOURCE_PORT - const word = 0
UDP_DESTINATION_PORT - const word = 2
UDP_LENGTH - const word = 4
UDP_CHECKSUM - const word = 6

Routines

  • print_udp_socket_info - Procedure
  • udp_data'get - Function returns byte
  • udp_data'put - Procedure
  • udp_error'get - Function returns byte
  • udp_init - Procedure
  • udp_read_packet - Procedure
  • udp_send - Procedure
  • udp_send_array - Procedure
  • udp_socket_create - Function returns byte
  • udp_socket_remove - Procedure


udp_init - JALlib Procedures Help

udp_init JALLIB PROCEDURE

Signature

procedure udp_init() is

Description

Init procedure

Include

To use this procedure, include the library:

include udp

Parameters

None

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: udp.jal


udp_send - JALlib Procedures Help

udp_send JALLIB PROCEDURE

Signature

procedure udp_send(byte in socket_name, word in data_size) is

Description

Sends a UDP packet containing data held in udp_data[] array. You
must specify the size of data written to udp_data[]
less ram usage and more cpu cycles then udp_send_array()

Include

To use this procedure, include the library:

include udp

Parameters

  • socket_name - byte in
  • data_size - word in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: udp.jal


udp_send_array - JALlib Procedures Help

udp_send_array JALLIB PROCEDURE

Signature

procedure udp_send_array(byte in socket_name, byte in data[]) is

Description

Sends a UDP packet from an input array (uses more memory space)
more ram usage and less cpu cycles then udp_send_array()

Include

To use this procedure, include the library:

include udp

Parameters

  • socket_name - byte in
  • data[] - byte in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: udp.jal


udp_socket_create - JALlib Procedures Help

udp_socket_create JALLIB FUNCTION

Signature

function udp_socket_create(word in local_port, word in remote_port) return byte is

Description

Create a new socket if one doesn't arleady exist. If a socket already
exists, return the socket.
If a socket was not created, var udp_error gets set.
remote_port - the port number the server uses
local_port - any port number that is avalable locally.

Include

To use this procedure, include the library:

include udp

Parameters

  • local_port - word in
  • remote_port - word in

Return Value

byte - Function return value

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: udp.jal


udp_socket_remove - JALlib Procedures Help

udp_socket_remove JALLIB PROCEDURE

Signature

procedure udp_socket_remove(byte in socket_number) is

Description

Celete/disconnect a socket.

Include

To use this procedure, include the library:

include udp

Parameters

  • socket_number - byte in

Return Value

None

Example

From sample file: 18f4620_network_all_in_one.jal

-- Title: All network protocols in one file on ENC28j60 BETA
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2011, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4n
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: All network protocols in one file on ENC28j60.
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
--
-- Notes:
-- This is being released as BETA.
--

-- include chip
include 18F4620                   -- target picmicro
-- this program assumes a 20 mhz resonator or crystal
-- is connected to pins osc1 and osc2.
pragma target osc INTOSC_NOCLKOUT              -- hs crystal or resonator
;pragma target osc hs              -- hs crystal or resonator
;pragma target clock 20_000_000    -- oscillator frequency
pragma target clock 32_000_000    -- oscillator frequency
--
pragma target wdt  CONTROL
pragma target lvp  enabled
pragma target MCLR external        -- reset externally
--;
;OSCCON_IRCF = 0b110   -- set int osc to 4mhz
OSCCON_IRCF = 0b111   -- set internal osc to 8mhz
OSCTUNE_PLLEN = true  -- multiply internal osc by 4
;--
_usec_delay(500_000)

include print

-- setup serial software
const serial_sw_baudrate = 115200
alias serial_sw_tx_pin is pin_B4
alias serial_sw_rx_pin is pin_B5
pin_B4_direction = output
pin_B5_direction = input
include serial_software
serial_sw_init()
alias serial_data is serial_sw_data

-- setup a button
alias button2 is pin_d0
alias button2_direction is pin_d0_direction
button2_direction = INPUT

-- setup a button
alias button is pin_d1
alias button_direction is pin_d1_direction
button_direction = INPUT

-- setup a button
alias button3 is pin_d3
alias button3_direction is pin_d3_direction
button3_direction = INPUT

-- setup a led
alias led is pin_d2
alias led_direction is pin_d2_direction
--
led_direction = OUTPUT
led = high

-- setup a led
alias led2 is pin_d4
alias led2_direction is pin_d4_direction
--
led2_direction = OUTPUT
led2 = high

-- setup a led
alias led3 is pin_b3
alias led3_direction is pin_b3_direction
--
led3_direction = OUTPUT
led3 = high

include spi_master_hw        -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_00,SPI_RATE_FOSC_4) -- init spi, choose mode and speed

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = TRUE    -- enables debugging
include debug
--
-- turn on and off debug levels.
;debug_lvl_0 = ON
debug_lvl_1 = ON   -- network error messages
debug_lvl_2 = ON   -- network general text
debug_lvl_3 = ON   -- network packet data type text
debug_lvl_4 = OFF  -- network raw data
;debug_lvl_5 = ON
;debug_lvl_6 = ON
--
var byte debug_text1[] = "DEBUG STARTED"
debug_string(DEBUG_2,debug_text1)
debug_crlf(DEBUG_2)

-- setup ENC28j60
-- pin def
alias enc_reset is pin_a2
alias enc_reset_direction is pin_a2_direction
enc_reset_direction = output
enc_reset = 1
--
-- interrupt output pin
alias enc_int is pin_a4
alias enc_int_direction is pin_a4_direction
enc_int_direction = input
--
-- wake up on lan signal (some datasheets say this pin is not connected?)
;alias enc_wol is pin_ax
;alias enc_wol_direction is pin_ax_direction
;enc_wol_direction = input
--
-- chip select pin
alias enc_cs is pin_e0
alias enc_cs_direction is pin_e0_direction
enc_cs_direction = output
enc_cs = 1
--
-- set constants for enc28j60
const byte ENC_LOCAL_MAC[6] = {0x00,0x13,0xD4,0xC6,0x53,0x16} -- MAC address of PIC
const ENC_USE_INTERRUPT_PIN = FALSE -- TRUE -> not tested yet
const ENC_ARRAY_SIZE = 1500 -- max 1500. Please adjust this, I was able to use 600
const ENC_ALWAYS_SET_SPI_MODE = TRUE
--
-- if you wish to store the array on an external memory device, create a
-- pseudo array here and name it enc_array[]
--
include enc28j60
enc_init()
--
-- change clockout pin freq. good communication test if you have a scope
enc_set_clkout_freq(ENC_8_333)
enc_set_clkout_freq(ENC_3_125)
--
-- print chip revision. another communcation test for those who don't
-- have a scope. My chip prints: 6
;for 10 loop
;   print_byte_dec(serial_data, enc_read_revision() )
;   serial_data = " "
;end loop

-- Setup Networking
-- choose network protocols to use
--
-- choose network protocols to use. You must put TRUE
-- for each protocol you use.
-- If you set FALSE or don't a define constant, don't include the file.
const NETWORK_USE_IP = TRUE
--
const NETWORK_USE_ARP = TRUE -- suggested for ethernet, not slip
const NETWORK_USE_ARP_CALLBACKS = TRUE
--
const NETWORK_USE_ICMP = TRUE -- required for ping only
const NETWORK_USE_ICMP_CALLBACKS = TRUE
--
const NETWORK_USE_UDP = TRUE -- udp can transfer data
const NETWORK_USE_UDP_CALLBACKS = TRUE
--
const NETWORK_USE_TCP = TRUE -- under development. requires ARP
const NETWORK_USE_TCP_CALLBACKS = TRUE
--
const byte network_local_ip[4] = {192,168,0,60}  -- IP address of PIC
const byte network_gateway_ip[4] = {192,168,0,1} -- IP address of gateway/router
--
-- set network layer
const NETWORK_LINK_LAYER = NETWORK_ETHERNET
const NETWORK_LINK_DEVICE = NETWORK_ENC28J60
--
const NETWORK_USE_TIMER = 1 -- timer not implemented yet, but will be needed.
--
-- include networking main files
include networking
include ethernet_mac
include ip_header
include arp

const ICMP_ECHO_DATA_LENGTH = 32 -- size of data to send with PING
include icmp

-- setup UDP
const byte UDP_MAX_SOCKETS = 10 -- max number of udp connections (9 bytes ram per connection)
const bit UDP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const bit UDP_CHECKSUM_OUT = FALSE -- TRUE not supported yet on outgoing packets
--
include udp
udp_init()
--
-- LOCAL UDP SERVER SETTINGS
const byte UDP_LOCAL_SERVER_PORT = 111 -- port of local UDP server
--
-- LOCAL UDP CLIENT SETTINGS
var byte udp_conn_1                       -- create a variable to be used as a udp client.
const word UDP_LOCAL_CLIENT_PORT = 1234        -- port of local UDP client
const word UDP_REMOTE_SERVER_PORT = 251        -- port of remote UDP server
network_set_remote_ip(192,168,0,10)       -- set IP of server to connect to.
udp_conn_1 = udp_socket_create(UDP_LOCAL_CLIENT_PORT,UDP_REMOTE_SERVER_PORT)  -- open a socket
;udp_socket_remove(udp_conn_1) -- I guess we'll never remove this socket

print_udp_socket_info(1,udp_conn_1)

-- setup TCP
const TCP_MAX_SOCKETS = 10 -- max number of TCP connections (9 bytes ram per connection)
const TCP_CHECKSUM_IN = FALSE -- TRUE not supported yet on incomming packets
const TCP_CHECKSUM_OUT = TRUE -- FALSE not supported yet. TCP MUST do checksum out??
--
include TCP
tcp_init()
--
-- LOCAL TCP SERVER SETTINGS
const byte TCP_LOCAL_SERVER_PORT = 222 -- port of local TCP server
--
-- LOCAL TCP CLIENT SETTINGS (NOTE: NOT FULLY TESTED, HAS ISSUES)
var byte tcp_conn_1                          -- create a variable to be used as a TCP client.
var word TCP_LOCAL_CLIENT_PORT = random_word -- port of local TCP client
const TCP_REMOTE_SERVER_PORT = 333           -- port of remote TCP server
network_set_remote_ip(192,168,0,10)          -- set IP of server to connect to.
tcp_conn_1 = tcp_socket_create(TCP_LOCAL_CLIENT_PORT,TCP_REMOTE_SERVER_PORT)  -- create a socket
--
-- connect to tcp client
network_set_remote_ip(192,168,0,10)
arp_get_mac(5,1_000)
tcp_connect(tcp_conn_1) -- connect to TCP server
;TCP_socket_remove(tcp_conn_1) -- I guess we'll never remove this socket

-- web server data for TCP
-- must at least contain:
-- "HTTP/1.1 200 OK\r\n"
-- "Content-Length: X\r\n"               (where X = length of data in bytes)
-- "Content-Type: text/html\r\n\r\n"
-- webpage data

const byte HTTP_HEADER[] = {

---
-- add your own options here:
---
-- "Date: Tue, 15 Feb  2011 20:05:58 GMT"
;0x44,0x61,0x74,0x65,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x31,0x35,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x32,0x30,0x3a,0x30,0x35,0x3a,0x35,0x38,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "Server: IBM_HTTP_Server/6.0 Apache/2.0.47 (Win32)"
;,0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x49,0x42,0x4d,0x5f,0x48,0x54,0x54,0x50,0x5f,0x53,0x65,0x72,0x76,0x65,0x72,0x2f,0x36,0x2e,0x30,0x20,0x41,0x70,0x61,0x63,0x68,0x65,0x2f,0x32,0x2e,0x30,0x2e,0x34,0x37,0x20,0x28,0x57,0x69,0x6e,0x33,0x32,0x29,0x0d,0x0a
;
-- "Last-Modi fied: Tue, 08 Feb 2011 08:35:43 GMT"
;,0x4c,0x61,0x73,0x74,0x2d,0x4d,0x6f,0x64,0x69,0x66,0x69,0x65,0x64,0x3a,0x20,0x54,0x75,0x65,0x2c,0x20,0x30,0x38,0x20,0x46,0x65,0x62,0x20,0x32,0x30,0x31,0x31,0x20,0x30,0x38,0x3a,0x33,0x35,0x3a,0x34,0x33,0x20,0x47,0x4d,0x54,0x0d,0x0a
;
-- "ETag: "1c043-8-3bea1437"
;,0x45,0x54,0x61,0x67,0x3a,0x20,0x22,0x31,0x63,0x30,0x34,0x33,0x2d,0x38,0x2d,0x33,0x62,0x65,0x61,0x31,0x34,0x33,0x37,0x22,0x0d,0x0a
;
-- "Accept-Ranges: bytes"
;,0x41,0x63,0x63,0x65,0x70,0x74,0x2d,0x52,0x61,0x6e,0x67,0x65,0x73,0x3a,0x20,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a
;
-- "Keep-Alive: timeout=10, max=100"
;,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x3a,0x20,0x74,0x69,0x6d,0x65,0x6f,0x75,0x74,0x3d,0x31,0x30,0x2c,0x20,0x6d,0x61,0x78,0x3d,0x31,0x30,0x30,0x0d,0x0a
;
-- "Connection: Keep-Alive"
;,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x4b,0x65,0x65,0x70,0x2d,0x41,0x6c,0x69,0x76,0x65,0x0d,0x0a,

-- "Content-Type: text/html\r\n"
0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a
, 0x0d, 0x0a
}

-- file names
const HTTP_FILE_NAME_LENGHT = 20 -- max length of a web page file name
const byte HTTP_FILE_1_NAME[] = "/"
const byte HTTP_FILE_2_NAME[] = "/INDEX.HTM"
const byte HTTP_FILE_3_NAME[] = "/Test.txt"
const byte HTTP_FILE_4_NAME[] = "/form.htm"

-- FILES
-- 404 file not found
const byte HTTP_FILE_0[] = "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>JALV2 WEB SERVER at test.justanotherlanguage.org Port 80</address></body></html>"
--
-- main page
;const byte HTTP_FILE_1[] = "" -- file 1 and file 2 are the same ("/" and "/INDEX.HTM")
const byte HTTP_FILE_2[] = "<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml'><head><meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1' /><title>Matt's JALv2/JALLib PIC Webserver</title></head><body><p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p><a href='/form.htm'>Click here for LED demo</a> </p></body></html>"
--
-- text file
const byte HTTP_FILE_3[] = "This is a test text file from PIC"
--
-- LED status page
const byte HTTP_FILE_4[] = "<p><strong>WELCOME TO MATT'S JALV2/JALLIB PIC WEBSERVER!</strong></p><p>Turn led on or off (values 1 or 0 are accepted)</p><form name='input' action='form.htm' method='post'>  Set LED Status:   <input type='text' name='led' /><input type='submit' value='Submit' /></form></br>"

const HTTP_USE_GET_CALLBACK = TRUE
const HTTP_SERVER_PORT = 80
include http

--MAIN PROGRAM-----------------------------------------------------------------------------------------------------

-- CALLBACK PROCEDURES --

--------------------------------------------------------------------------------
-- called when a web page is requested
--------------------------------------------------------------------------------
procedure http_callback(byte in socket,byte in http_file_name[]) is
   -- set http data
   var word step

   -- print file name requested
   for count(http_file_name) using step loop
      serial_data = http_file_name[step]
   end loop

   -- if http POST command
   if string_compare_mid(http_command,0,HTTP_STRING_POST) then

      -- send post data to serial port
      ;var byte temp
      ;for http_data_size using temp loop
      ;   serial_data = http_data[temp]
      ;end loop

      -- store post data
      var byte post_data[50]
      for http_data_size using step loop
         post_data[step] = http_data[step]
      end loop

      -- get led's value
      const byte LED_NAME[] = "LED"
      led = http_data[count(LED_NAME) + 1] - "0"

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then

         -- set web page data
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

;         -- put post data at bottom of web page
;         for http_data_size using temp loop
;            http_data[step] = post_data[temp]
;            step = step + 1
;         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if

   -- if http GET command
   elsif string_compare_mid(http_command,0,HTTP_STRING_GET) then

      -- if webpage 4 "/form.htm"
      if http_is_filename(HTTP_FILE_4_NAME) then
         for count(HTTP_FILE_4) using step loop
            http_data[step] = HTTP_FILE_4[step]
         end loop

         -- put led status text bottom of web page
         const byte LED_STATUS_ON[]  = "THE LED IS CURRENTLY ON "
         const byte LED_STATUS_OFF[] = "THE LED IS CURRENTLY OFF"
         var byte status_step
         for count(LED_STATUS_ON) using status_step loop
            if led == 0 then
               http_data[step] = LED_STATUS_OFF[status_step]
            elsif led == 1 then
               http_data[step] = LED_STATUS_ON[status_step]
            end if
            step = step + 1
         end loop

      -- if webpage 3 "/Test.txt"
      elsif http_is_filename(HTTP_FILE_3_NAME) then
         for count(HTTP_FILE_3) using step loop
            http_data[step] = HTTP_FILE_3[step]
         end loop

      -- if webpage 2 "/" OR "/INDEX.HTM
      elsif http_is_filename(HTTP_FILE_2_NAME) | http_is_filename(HTTP_FILE_1_NAME) then
         for count(HTTP_FILE_2) using step loop
            http_data[step] = HTTP_FILE_2[step]
         end loop

      -- if page not found
      else
         for count(HTTP_FILE_0) using step loop
            http_data[step] = HTTP_FILE_0[step]
         end loop
      end if
   end if

   -- you must set webpage size at the end of this procedure
   webpage_size = step
end procedure

--------------------------------------------------------------------------------
-- called when we get a arp reply from an external source
--------------------------------------------------------------------------------
procedure arp_reply_callback() is
    -- print a message
    var byte get_arp[] = "ARP Reply Recieved!"
    print_string(serial_data,get_arp)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a arp request
--------------------------------------------------------------------------------
procedure arp_request_callback() is
    -- print a message
    var byte get_ping[] = "arp request recieved, sending reply"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- called when we get a ping reply (after we sent a ping out somewhere)
--------------------------------------------------------------------------------
procedure icmp_echo_reply_callback() is
    -- print a message
    var byte get_ping[] = "ping reply recieved!"
    print_string(serial_data,get_ping)
    print_crlf(serial_data)
end procedure
--------------------------------------------------------------------------------
-- called when we get a ping from an external source
--------------------------------------------------------------------------------
procedure icmp_echo_callback() is
      led2 = !led2 -- toggle led
end procedure

--------------------------------------------------------------------------------
-- Called when UDP packet is received. Minumum data size is 18 bytes.
--------------------------------------------------------------------------------
procedure udp_receive_callback(byte in socket,word in udp_data_size) is
   -- print info about the socket received
   print_udp_socket_info(0,socket)

   -- if there was an error
   if udp_error != 0 then
   end if

   -- if it is our server connection
   -- if a client is sending information to our UDP server on PIC.
   if udp_socket_local_port[socket] == UDP_LOCAL_SERVER_PORT then
      -- do something with the data, we'll print it to serial port
      var word step
      for udp_data_size using step loop               -- for each byte in packet
         serial_data = udp_data[step]
      end loop

      -- maybe you want to talk back to the client?
      -- send a reply message
      udp_data[0] = "T"
      udp_data[1] = "H"
      udp_data[2] = "A"
      udp_data[3] = "N"
      udp_data[4] = "K"
      udp_data[5] = "S"
      udp_data[6] = "!"

      print_crlf(serial_data)
      var byte sending_udp[] = "Sending reply UDP data" -- print a message
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)
      udp_send(socket,7)        -- send 7 bytes data to socket

      udp_socket_remove(socket) -- remove the socket
   else

      -- if it is our client connection
      -- if we had sent information to a server, and the server replyed on same port.
      if udp_socket_local_port[socket] == UDP_LOCAL_CLIENT_PORT &
         udp_socket_ip[socket] == udp_socket_ip[udp_conn_1] then
         -- do something with the data, we'll print it to serial port
         var word step
         for udp_data_size using step loop               -- for each byte in packet
            serial_data = udp_data[step]
         end loop
      end if

   ;   -- If it is our client connection
   ;   -- you can use this method if the server reply's using
   ;   -- the same source port as the server.
   ;   -- This is untested since my PC programming software does not
   ;   -- do this.
   ;   if socket == udp_conn_1 then
   ;       print_crlf(serial_data)
   ;       var byte sending_udp[] = "Welcome client!" -- print a message
   ;       print_string(serial_data,sending_udp)
   ;       print_crlf(serial_data)
   ;
   ;      -- do something with the data, we'll print it to serial port
   ;      var word step
   ;      for udp_data_size using step loop               -- for each byte in packet
   ;         serial_data = udp_data[step]
   ;      end loop
   ;   end if
   ;   udp_socket_remove(socket) -- remove the socket

   end if

   print_crlf(serial_data)
end procedure

--------------------------------------------------------------------------------
-- Receive TCP data.
--------------------------------------------------------------------------------
procedure tcp_receive_callback(byte in socket,word in tcp_data_size) is

   -- do webserver stuff
   http_server(socket,tcp_data_size)

   -- if it is our server connection
   -- if a client is sending information to our TCP server on PIC.
   if tcp_socket_local_port[socket] == TCP_LOCAL_SERVER_PORT then
      -- send data to serial port
      var word step
      for tcp_data_size using step loop -- for each byte in packet
         ;print_byte_hex(serial_data,tcp_data[step])
         serial_data = tcp_data[step]
      end loop

      -- you must send an ack. Set the size of data you wish to send.
      tcp_send_ack(socket,0)
   else

      -- if it is our client connection
      -- print data to serial port
      if socket == tcp_conn_1 then
         -- send incomming data to serial port
         var word step
         for tcp_data_size using step loop -- for each byte in packet
            ;print_byte_hex(serial_data,tcp_data[step])
            serial_data = tcp_data[step]
         end loop
      end if
   end if

   print_crlf(serial_data)
end procedure

-- MAIN PROGRAM LOOP --

-- print some start characters
for 10 loop
   serial_data = "!"
end loop
print_crlf(serial_data)

-- get the MAC of the gateway we will be talking to
network_set_remote_ip(192,168,0,1) -- ip address of your PC or router
;network_set_remote_ip(192,168,2,2)
-- print message
var byte sending_arp[] = "sending arp request, waiting for reply..."
print_string(serial_data,sending_arp)
print_crlf(serial_data)
--
if NETWORK_LINK_LAYER == NETWORK_ETHERNET then
   arp_get_mac(5,1_000)

   -- Get all the packets before we continue
   -- This is extra, it will just allow the next message to be
   -- printed last -> "You are connected! Your Router or PC mac address is:"
   for 1000 loop
      -- poll to see if there are network packets available
      network_poll()
   end loop

end if
--
if arp_reply_received == TRUE then
   print_crlf(serial_data)
   var byte get_arp[] = "You are connected! Your Router or PC mac address is:"
   print_string(serial_data,get_arp)
   print_crlf(serial_data)
   --
   print_byte_hex(serial_data,network_remote_mac[0])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[1])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[2])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[3])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[4])
   serial_data = "-"
   print_byte_hex(serial_data,network_remote_mac[5])
   print_crlf(serial_data)
   print_crlf(serial_data)
else
   print_crlf(serial_data)
   var byte arp_error[] = "ERROR: ARP did not get a reply. Is your network connected correctly?"
   print_string(serial_data,arp_error)
   print_crlf(serial_data)
end if

;-- uncomment if you are using WIN XP slip connection
;if NETWORK_LINK_LAYER == NETWORK_SLIP Then
;   -- wait for "CLIENT" from windows slip connection (yes, i got lazy)
;   while !serial_hw_data_available loop
;   end loop
;
;   -- reply with "CLIENTSERVER" to initiate connection
;   const byte str1[] = "CLIENTSERVER"   -- define a string
;   print_string(serial_hw_data, str1)   -- send via serial port
;end if

-- main loop
var word packet_size
forever loop
   -- send ping when button is pressed
   if button == LOW then

      -- print a message
      print_crlf(serial_data)
      var byte sending_ping[] = "sending ping!"
      print_string(serial_data,sending_ping)
      print_crlf(serial_data)

      network_set_remote_ip(192,168,0,10)  -- ip address of local network PC
      ;network_set_remote_ip(74,125,115,106)  -- ping google's ip address
      arp_get_mac(5,1_000)                   -- get mac address for ethernet layer
      icmp_send_echo()                       -- send an icmp echo (ping) request

      while button == LOW loop
         _usec_delay(100_000)
      end loop

   end if

   -- Send data via UDP when button is pressed
   if button2 == LOW then
      -- print a message
       print_crlf(serial_data)
      var byte sending_udp[] = "sending UDP data to UDP server"
      print_string(serial_data,sending_udp)
      print_crlf(serial_data)

      -- get mac of remote
      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

       -- set remote ip
      ;      network_set_remote_ip(192,168,0,1055)
      ;      network_set_remote_ip(192,168,2,2)
       ;network_set_remote_ip(192,168,0,105)

       -- EXAMPLE 1: Send data from udp_data[] internal array
       -- less ram usage and more cpu cycles then udp_send_array()
       -- send UDP data "HELLO"
       udp_data[0] = "H"                                 -- set data
       udp_data[1] = "E"
       udp_data[2] = "L"
       udp_data[3] = "L"
       udp_data[4] = "O"
       --
       ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
       --
       print_udp_socket_info(1,udp_conn_1) -- print socket info

       --
       if udp_error == 0 then                     -- if there are no errors
          var byte sending_udp[] = "Sending UDP data" -- print a message
          print_string(serial_data,sending_udp)
          print_crlf(serial_data)
          udp_send(udp_conn_1,5)         -- send 5 bytes data to udp_conn_1
       else
          var byte udp_error[] = "UDP ERROR - NO SOCKETS AVAILABLE" -- print a message
          print_string(serial_data,udp_error)
          print_crlf(serial_data)
       end if

       --
       ;udp_socket_remove(udp_conn_1) -- remove the socket

      ;      -- EXAMPLE 2: Send an array
      ;      -- more ram usage and less cpu cycles then udp_send()
      ;      -- send the data (source port, destination port, data)
      ;      --
      ;      ;udp_conn_1 = udp_socket_create(1234,UDP_LOCAL_CLIENT_PORT) -- connect
      ;      --
      ;      print_udp_socket_info(1,udp_conn_1) -- print socket info
      ;      --
      ;      var byte test[] = "HELLO WORLD"                   -- set data
      ;      if udp_error == 0 then                            -- if there are no errors
      ;         var byte sending_udp[] = "Sending UDP data"    -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;         udp_send_array(udp_conn_1,test)                -- send udp data
      ;      else
      ;         var byte sending_udp[] = "UDP error occurred"  -- print a message
      ;         print_string(serial_data,sending_udp)
      ;         print_crlf(serial_data)
      ;      end if
      ;      ;udp_socket_remove(udp_conn_1)                 -- remove

      while button2 == LOW loop
        _usec_delay(100_000)
      end loop

   end if

   -- Send data via TCP when button is pressed
   if button3 == LOW then
      -- print a message
      var byte sending_tcp[] = "sending TCP data to TCP server"
      print_string(serial_data,sending_tcp)
      print_crlf(serial_data)

      while button3 == LOW loop
         _usec_delay(100_000)
      end loop

      network_set_remote_ip(192,168,0,10)
      arp_get_mac(5,1_000)

      tcp_data[0] = "T"
      tcp_data[1] = "E"
      tcp_data[2] = "S"
      tcp_data[3] = "T"

      tcp_send(tcp_conn_1, 4)

   end if

   -- poll to see if there are network packets available
   network_poll()

end loop

Generated by JALlib CHM Help System | Source: udp.jal


unittest.jal - JALLIB Library Documentation

unittest.jal JALLIB LIBRARY

Title

unittests procedures

Author

Sebastien Lelong, Copyright (c) 2009, all rights reserved.

Compiler

>=2.4k

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

set of procedures used to perform unittest

Routines

  • test_bit - Procedure
  • test_byte - Procedure
  • test_dword - Procedure
  • test_sdword - Procedure
  • test_sword - Procedure
  • test_word - Procedure


usart2_common.jal - JALLIB Library Documentation

usart2_common.jal JALLIB LIBRARY

Title

USART2 common

Author

Stef Mientki Copyright (c) 2002..2010, all rights reserved., Adapted-by: Sebastien Lelong, Joep Suijs, Rob Hamerling

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

USART2 common functions
This file provides common functions to other libraries.
.
Baudrate can simply be set through a constant in the application program,
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.

Constants and Variables

usart_hw2_serial - const bit = TRUE -- default is async mode (not sync)
default is async mode (not sync)

Routines

  • _calculate_and_set_baudrate2 - Procedure


usart3_common.jal - JALLIB Library Documentation

usart3_common.jal JALLIB LIBRARY

Title

UART3 common.

Author

Rob Jansen, Copyright (c) 2021..2021 all rights reserved., Adapted-by:

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

USART3 common functions.
This file provides common functions to other libraries.

Notes

Baudrate can simply be set through a constant in the application
program, 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.
The 8-bit baudrate generator is not supported by this library since
it is assumed that for these newer USARTS this is no longer used.

Sources

Based on the uart2_common.jal llibrary by Stef Mientki.
-----------------------------------------------------------------------------

Constants and Variables

usart_hw3_serial - const bit = TRUE -- default is async mode (not sync)
default is async mode (not sync)

Routines

  • _calculate_and_set_baudrate3 - Procedure


usart_common.jal - JALLIB Library Documentation

usart_common.jal JALLIB LIBRARY

Title

USART common

Author

Stef Mientki Copyright (c) 2002..2010, all rights reserved., Adapted-by: Sebastien Lelong, Joep Suijs, Rob Hamerling

Compiler

2.4o

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

USART common functions
This file provides common functions to other libraries.
.
Baudrate can simply be set through a constant in the application program,
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.

Constants and Variables

usart_hw_serial - const bit = TRUE -- default is async mode (not sync)
default is async mode (not sync)

Routines

  • _calculate_and_set_baudrate - Procedure


usb_cdc_line_status - JALlib Procedures Help

usb_cdc_line_status JALLIB FUNCTION

Signature

function usb_cdc_line_status() return byte is

Description

This function returns the line status. If on the host side the COM port has not been
opened, the return status will be 0x00, otherwise it will be != 0

Include

To use this procedure, include the library:

include usb_drv_cdc_class

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1455_tutorial_usb_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Tutorial USB Serial Demo
-- Author: Rob Jansen, Copyright (c) 2022..2024, all rights reserved.
-- Adapted-by: Rob Hamerling, Rob Jansen
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This application demonstrates the functionality of the USB Serial library,
--              this application will emulate a RS-232 terminal device. Once the USB device
--              has been detected by the host operating system, it will create a virtual
--              serial (COM) port. When opening this port on the host computer using a
--              standard terminal application 2 LEDs can remotely be controlled.
--              The status of the LEDs is returned to the host.-
--
--
-- Notes: For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
--        the USB connection and the PIC16F1455 is connected as follows:
--        *) USB data- wire to pin 12 (A1 / D-)
--        *) USB data+ wire to pin 13 (A0 / D+)
--        *) USB power wire to pin 1 (VDD). Don't forget a 100nF decoupling capacitor.
--        *) USB ground wire to pin 14 (VSS or GND)
--        *) A resistor of 33kOhm to pin 4 (MCLR) and VDD. We use internal reset.
--        *) A capacitor of 470nF to pin 11 (Vusb3v3) and GND.
--        *) A Yellow LED with 330 Ohm resistor to pin 8 (C2).
--           (indicates that USB is configured.)
--        *) A Red LED with 330 Ohm resistor to pin 6 (C4).
--        *) A Green LED with 330 Ohm resistor to pin 7 (C3).
--
--        For In Circuit Serial Programming:
--        *) ICSPDAT wire to pin 10 (C0)
--        *) ICSPCLK wire to pin 9 (C1)
--
include 16f1455             -- Target processor.

pragma target clock         48_000_000

-- Settings for internal clock and system clock 48 MHz.
pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses.
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- External reset
pragma target LVP           ENABLED  -- allow low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a and and set port c to output just to
-- have no floating input pins.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1111          -- Weak-pull up for all inputs.
TRISC         = 0b0000_0000          -- Port c output.

-- Include serial library and print library for formatting print output.
include usb_serial
include print

-- Aliases for LEDs, active HIGH.
alias led_red is pin_C4
pin_C4_direction = output            -- Pin 6 of 14 pin DIP.
alias led_green is pin_C3
pin_C3_direction = output            -- Pin 7 of 14 pin DIP.
alias led_yellow is pin_C2
pin_C2_direction = output            -- Pin 8 of 14 pin DIP.

-- Variables.
var byte character
var bit red_value, green_value

-- ------------- The main program starts here  ------------------------

-- Setup the USB serial library.
usb_serial_init()

-- LEDs off.
led_yellow = FALSE
red_value = FALSE
green_value = FALSE

forever loop

   -- Update Red and Green LEDs.
   led_red = red_value
   led_green = green_value

   -- Poll the usb ISR function on a regular base,
   -- in order to serve the USB requests
   usb_serial_flush()

   -- Check if USB device has been configured by the host.
   if ( usb_cdc_line_status() !=  0x00 )  then
      led_yellow = TRUE
   else
      led_yellow = FALSE    -- disconnected
      red_value = FALSE     -- red led off
      green_value = FALSE   -- green led off
   end if

   -- Check for input character. If OK, toggle led value and report to host.
   if usb_serial_read(character) then
      if (character == "R") | (character == "r") then
         red_value = !red_value
         print_string(usb_serial_data, "Red LED is ")
         if red_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      elsif (character == "G") | (character == "g") then
         green_value = !green_value
         print_string(usb_serial_data, "Green LED is ")
         if green_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      else
         print_string(usb_serial_data, "Expecting 'r' or 'g'")
      end if
      print_crlf(usb_serial_data)
   end if

end loop
--

Generated by JALlib CHM Help System | Source: usb_drv_cdc_class.jal


usb_defs.jal - JALLIB Library Documentation

usb_defs.jal JALLIB LIBRARY

Title

USB constant definitions

Author

Albert Faber, Copyright (c) 2008..2021, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Constants for configurting the USB interface

Notes

Set the base address of the USB dual port memory location
this address actually corresponds to the location of BDT
(Buffer Descriptor Table). USB RAM is divided into two main
areas: BDT and USB data. In some PIC, USB RAM starts with BDT
and then is followed by USB data. But for some others (like 18FX7J53)
part of USB data can be located *before* BDT. For now, USB implementation
assumes USB RAM is structured as BDT then USB data (contiguous).
Strictly speaking and consequently (and as a matter of semantic),
USB_BASE_ADDRESS corresponds to BDT, but as USB_BASE_ADDRESS is used in many
libs and samples (and user code), and since current implementation isn't able
to use USB data *before* BDT, we're aliasing BDT to this variable.

RJ: Some notes about addresses, the memory map and the buffers used
-------------------------------------------------------------------
The USB_BDT_ADDRESS can differ per PIC. Also the memory bank(s) defined for
use for USB are not continuous for all PICs. For example the PIC18F14K50
has 256 bytes of continuous USB memory from 0x200 - 0x2ff but the PIC16F1455
has 512 bytes of USB memory starting at linear address 0x2000 but since we can
only used banked addressing starting at 0x020, buffers sizes are limited to
80 bytes for these PICs.
In the USB driver the following USB buffers with sizes are used:
*) usb_bd_array[80]. This buffer holds all buffer descriptions. This driver
only uses 8 (4 in and 4 out) buffer descriptions of 4 bytes so only 32
bytes are actually used.
*) usb_sdp_buffer[8]. Buffer that holds the data of the SETUP packet.
*) usb_epxout_buf[8] and usb_epxin_buf[8] where x = 0..3. These are the
end point buffers. The number of buffers used depend on the type of USB
device. The maximum currently in use are 4 (0..3) endpoint buffers so in
total 64 bytes.
*) usb_delivery_buffer[80]. This buffer should be capable of holding a complete
device descriptor which is at most of 67 bytes
For the PIC16F1454/55/59 we use the banks with the following addresses:
*) usb_bd_array starting at USB_BASE_ADDRESS + 0x0000 (first bank)
*) usb_sdp_buffer starting at USB_BASE_ADDRESS + 0x0020 (first bank)
*) usb_epxoutbuf starting at USB_BASE_ADDRESS + 0x0080 (second bank)
*) usb_delivery_buffer starting at USB_BASE_ADDRESS + 0x0100 (third bank)
For the PIC18F14K50 we do not use use banks but the following addresses:
*) usb_bd_array starting at USB_BASE_ADDRESS + 0x0000 (32 bytes)
*) usb_epxoutbuf starting at USB_BASE_ADDRESS + 0x0020 (88 bytes)
*) usb_delivery_buffer starting at USB_BASE_ADDRESS + 0x0078 (80 bytes)
*) usb_sdp_buffer starting at USB_BASE_ADDRESS + 0x00f8 (8 bytes)
Note: Since arrays are declared at a certain address we must make sure that
all used memory locations are reserved so that the compiler knows
they are used. Because of this a dummy buffer usb_bd_endpt[80]
is also declared for the PIC16F1455 which reserves the required space
for the usb_epxoutbuf and usb_epxinbuf.

------- Some aliases to get things working for different PICs ---------------
Interrupt aliases:

Sources

http://www.usb.org for USB specifications

Constants and Variables

USB_IN_DELIVERY_BUFFER_LOC - const word = ( USB_BASE_ADDRESS + 0x0100 )
USB_IN_DELIVERY_BUFFER_LOC - const word = ( USB_BASE_ADDRESS + 0x0078 )
USB_DELIVERY_BUFFER_MAX_SIZE - const byte = 80
usb_delivery_bytes_max_send - var byte
usb_delivery_bytes_sent - var byte
usb_delivery_buffer_size - var byte
usb_delivery_bytes_to_send - var byte
USB_DEBUG - const bit = false
USB_DEBUG_HIGH - const bit = false
USB_HIGHEST_EP - const byte = 3
USB_SELF_POWERED - const bit = 1
usb_sdp_loc - const word = ( USB_BASE_ADDRESS + 0x0020 )
usb_sdp_loc - const word = ( USB_BASE_ADDRESS + 0x00F8 )
USB_STATUS_IDLE - const byte = 0
USB_STATUS_SET_ADDRESS - const byte = 1
USB_STATE_POWERED - const byte = 0 -- USB device is powered up, ready to start negotiating
USB device is powered up, ready to start negotiating
USB_STATE_DEFAULT - const byte = 1 -- USB device is now negotiating
USB device is now negotiating
USB_STATE_ADDRESS - const byte = 2 -- USB device now has an address
USB device now has an address
USB_STATE_CONFIGURED - const byte = 3 -- USB device is completely configured and ready to rock and roll
USB device is completely configured and ready to rock and roll
USB_CM_IDLE - const byte = 0 -- No control transfer taking place
No control transfer taking place
USB_CM_CTRL_WRITE_DATA_STAGE - const byte = 1 -- Device receiving data during the data stage
Device receiving data during the data stage
USB_CM_CTRL_WRITE_DATA_STAGE_CLASS - const byte = 2 -- Device receiving data during the data stage destined for the class
Device receiving data during the data stage destined for the class
USB_CM_CTRL_READ_DATA_STAGE - const byte = 3 -- Device sending data during the data stage
Device sending data during the data stage
USB_CM_CTRL_READ_DATA_STAGE_CLASS - const byte = 4 -- Device class is sending data during the data stage
Device class is sending data during the data stage
USB_CM_CTRL_READ_AWAITING_STATUS - const byte = 5 -- Device is awaiting reception of status after sending data
Device is awaiting reception of status after sending data
USB_CM_CTRL_WRITE_SENDING_STATUS - const byte = 6 -- Device is sending status after receiving data
Device is sending status after receiving data
USB_REQUEST_GET_STATUS - const byte = 0x00
USB_REQUEST_CLEAR_FEATURE - const byte = 0x01
USB_REQUEST_SET_FEATURE - const byte = 0x03
USB_REQUEST_SET_ADDRESS - const byte = 0x05
USB_REQUEST_GET_DESCRIPTOR - const byte = 0x06
USB_REQUEST_SET_DESCRIPTOR - const byte = 0x07
USB_REQUEST_GET_CONFIGURATION - const byte = 0x08
USB_REQUEST_SET_CONFIGURATION - const byte = 0x09
USB_REQUEST_GET_INTERFACE - const byte = 0x0a
USB_REQUEST_SET_INTERFACE - const byte = 0x0b
USB_REQUEST_REQ_SYNCH_FRAME - const byte = 0x0c
USB_BDSTATUS_UOWN - const byte = 7 -- 0 if uC owns buffer
0 if uC owns buffer
USB_BDSTATUS_DTS - const byte = 6 -- 1 data 1 packet, 0 data 0 packet
1 data 1 packet, 0 data 0 packet
USB_BDSTATUS_KEN - const byte = 5 -- 1 USB will keep buffer indefinately, 0 USB will hand back buffer
1 USB will keep buffer indefinately, 0 USB will hand back buffer
USB_BDSTATUS_INCDIS - const byte = 4 -- 1 Address increment disabled (for SPP), 0 address increment enabled
1 Address increment disabled (for SPP), 0 address increment enabled
USB_BDSTATUS_DTSEN - const byte = 3 -- 1 data toggle sync on, 0 data toggle sync off
1 data toggle sync on, 0 data toggle sync off
USB_BDSTATUS_BSTALL - const byte = 2 -- 1 buffer stall enabled, 0 buffer stall disabled
1 buffer stall enabled, 0 buffer stall disabled
USB_BDSTATUS_BC9 - const byte = 1 -- bit 9 of buffer count
bit 9 of buffer count
USB_BDSTATUS_BC8 - const byte = 0 -- bit 8 of buffer count
bit 8 of buffer count
USB_PID_OUT - const byte = 0b00000001
USB_PID_IN - const byte = 0b00001001
USB_PID_SOF - const byte = 0b00000101
USB_PID_SETUP - const byte = 0b00001101
USB_PID_DATA0 - const byte = 0b00000011
USB_PID_DATA1 - const byte = 0b00001011
USB_PID_DATA2 - const byte = 0b00000111
USB_PID_MDATA - const byte = 0b00001111
USB_PID_ACK - const byte = 0b00000010
USB_PID_NAK - const byte = 0b00001010
USB_PID_STALL - const byte = 0b00001110
USB_PID_NYET - const byte = 0b00000110
usb_state - var byte = USB_STATE_POWERED
usb_status - var byte = USB_STATUS_IDLE
usb_control_mode - var byte = USB_CM_IDLE
usb_address - var byte = 0
USB_DT_DEVICE - const byte = 0x01
USB_DT_CONFIGURATION - const byte = 0x02
USB_DT_STRING - const byte = 0x03
USB_DT_INTERFACE - const byte = 0x04
USB_DT_ENDPOINT - const byte = 0x05
USB_DT_DEVICE_QUALIFIER - const byte = 0x06
USB_DT_OTHER_SPEED_CONFIG - const byte = 0x07
USB_DT_INTERFACE_POWER - const byte = 0x08
USB_DT_OTG - const byte = 0x09
USB_DT_DEBUG - const byte = 0x0a
USB_DT_INTERFACE_ASSOC - const byte = 0x0b
USB_DT_HID - const byte = 0x21
USB_DT_HID_REPORT - const byte = 0x22
USB_DT_CS_INTERFACE - const byte = 0x24
USB_EP_CTRL - const byte = 0x06 -- Cfg Control pipe for this ep
Cfg Control pipe for this ep
USB_EP_OUT - const byte = 0x0C -- Cfg OUT only pipe for this ep
Cfg OUT only pipe for this ep
USB_EP_IN - const byte = 0x0A -- Cfg IN only pipe for this ep
Cfg IN only pipe for this ep
USB_EP_OUT_IN - const byte = 0x0E -- Cfg both OUT & IN pipes for this ep
Cfg both OUT & IN pipes for this ep
USB_HSHK_EN - const byte = 0x10 -- Enable handshake packet
Enable handshake packet
USB_CDC_DEVICE - const byte = 0x02
USB_COMM_INTF - const byte = 0x02
USB_VENDOR_INTF - const byte = 0xFF
USB_ABSTRACT_CONTROL_MODEL - const byte = 0x02
USB_V25TER - const byte = 0x01 -- Common AT commands ("Hayes(TM)")
Common AT commands ("Hayes(TM)")
USB_BD_STAT_IDX - const byte = 0x00
USB_BD_CNT_IDX - const byte = 0x01
USB_BD_ADDRH_IDX - const byte = 0x02
USB_BD_ADDRL_IDX - const byte = 0x03
USB_HID_INTF - const byte = 0x03
USB_BOOT_INTF_SUBCLASS - const byte = 0x01
USB_HID_PROTOCOL_NONE - const byte = 0x00
USB_HID_PROTOCOL_KEYBOARD - const byte = 0x01
USB_HID_PROTOCOL_MOUSE - const byte = 0x02
USB_EPT_CTRL - const byte = 0x00 -- Control Transfer
Control Transfer
USB_EPT_ISO - const byte = 0x01 -- Isochronous Transfer
Isochronous Transfer
USB_EPT_BULK - const byte = 0x02 -- Bulk Transfer
Bulk Transfer
USB_EPT_INT - const byte = 0x03 -- Interrupt Transfer
Interrupt Transfer
USB_PULLUP_ENABLE - const byte = 0x10
USB_PULLUP_DISABLED - const byte = 0x00
USB_INTERNAL_TRANSCEIVER - const byte = 0x00
USB_EXTERNAL_TRANSCEIVER - const byte = 0x08
USB_FULL_SPEED - const byte = 0x04
USB_LOW_SPEED - const byte = 0x00
USB_PING_PONG__NO_PING_PONG - const byte = 0x00 -- 0b00
0b00
USB_PING_PONG__EP0_OUT_ONLY - const byte = 0x01 -- 0b01
0b01
USB_PING_PONG__FULL_PING_PONG - const byte = 0x02 -- 0b10
0b10
USB_PING_PONG__ALL_BUT_EP0 - const byte = 0x03 -- 0b11
0b11


usb_disconnected_tasks - JAL Language Syntax Reference

usb_disconnected_tasks SYNTAX

Description:
Test program for USB MSD (Mass Storage Device) with SD card. -- -- Here are my speed tests: -- Read Speed (SD_READ_EXTRA_SPEED = TRUE) - 205KB/s (usb only) -- Read Speed (SD_READ_EXTRA_SPEED = FALSE) - 108KB/s -- Write Speed - 110KB/s -- -- This file has been generated by hand (manually maintained) -- -- Sources: -- http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf -- http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf -- http://direction.scene-double.com/2008/07/08/usb-msd-bootloader-for-pic-microcontrollers.aspx --

Notes

-- include 18f67j50 -- target PICmicro -- -- This program uses the internal oscillator with PLL active. pragma target clock 48_000_000 -- oscillator frequency -- pragma target OSC INTOSC_NOCLKOUT_PLL -- internal oscillator pragma target PLLDIV P2 -- 8 MHz -> 4 MHz pragma target CPUDIV P1 -- Fosc divisor pragma target WDT CONTROL -- watchdog pragma target XINST DISABLED -- extended instruction set pragma target DEBUG DISABLED -- debugging pragma target FCMEN DISABLED -- clock monitoring pragma target IESO DISABLED -- int/ext osc. switch -- -- The configuration bit settings above are only a selection, sufficient -- for this program. Other programs may need more or different settings. -- WDTCON_SWDTEN = OFF -- disable WDT OSCCON_SCS = 0 -- select primary oscillator OSCTUNE_PLLEN = TRUE -- use PLL -- enable_digital_io() -- make all pins digital I/O -- include delay -- library with delay procedures const PRINT_MAX_VAR_SIZE = 6 include print -- setup uart for communication const serial_hw_baudrate = 115200 -- set the baudrate include serial_hardware serial_hw_init() -- some aliases so it is easy to change from serial hw to serial sw. alias serial_write is serial_hw_write alias serial_read is serial_hw_read alias serial_data is serial_hw_data alias serial_data_available is serial_hw_data_available -- setup SPI library include spi_master_hw -- includes the spi library -- define spi inputs/outputs pin_sdi_direction = input -- spi input pin_sdo_direction = output -- spi output pin_sck_direction = output -- spi clock -- spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed alias spi_master is spi_master_hw alias spi_master_exchange is spi_master_hw_exchange include format -- enable usb debugging const bit USB_DEBUG = FALSE const bit USB_DEBUG_HIGH = FALSE ;const bit USB_HID_DEBUG = TRUE ;const bit USB_HID_DEBUG_HIGH = TRUE -- setup debug lib alias debug_data is serial_data const bit DEBUG_MASTER_ENABLE = OFF -- enables debugging include debug -- -- turn on and off debug levels. debug_lvl_0 = ON -- short debugging debug_lvl_1 = OFF -- display data in/out debug_lvl_2 = OFF -- display commands debug_lvl_3 = OFF -- short debug info -- const byte debug_text0[] = "DEBUG STARTED" debug_string(DEBUG_0,debug_text0) debug_crlf(DEBUG_0) -- -- setup the sd card pins alias sd_chip_select is pin_SS alias sd_chip_select_direction is pin_SS_direction sd_chip_select = high sd_chip_select_direction = output -- -- setup the sd card library alias sd_force_spi_mode is spi_master_hw_set_mode_11 -- always set spi mode to 1,1 const bit SD_READ_EXTRA_SPEED = TRUE include sd_card -- include the sd card ide hard disk library sd_init() -- initialize startup settings -- if sd_has_error == TRUE then const byte SD_HAS_ERROR_MESSAGE[] = "ERROR - SD CARD FAILED" print_string(serial_data, SD_HAS_ERROR_MESSAGE) end if -- setup MSD library include usb_msd usb_msd_init() print_crlf(serial_data) print_string(serial_data,"Your mass storage device size is ") print_maxvar_dec(serial_data,byte*6(usb_msd_num_of_blocks)*512) print_string(serial_data," bytes.") -------------------------------------------------------------------------------- -- main Program -------------------------------------------------------------------------------- -- define procedures and variables

Example

procedure usb_connected_tasks()
var word char_count = 0
var word usb_check = 0
var byte usb_connected = TRUE

-- main loop to serve USB
forever loop
   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- Check if usb is still connected
   -- Another way would be to check the voltage on a USB+ pin.
   if USB_EVENT_OCCURRED == 1 then
      usb_check = 0
   elsif usb_check == 0xFFFF then
      -- USB is not connected
      usb_disconnected_tasks() -- perform your tasks
   else
      -- USB is connected
      usb_connected_tasks()
      usb_check = usb_check + 1
   end if

Generated by JAL Syntax Documentation System | Source: DITA


usb_drv.jal - JALLIB Library Documentation

usb_drv.jal JALLIB LIBRARY

Title

USB driver library

Author

Albert Faber, Copyright (c) 2008..2021, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This file contains the lowl level USB driver routines. It constrols
the USB serial interface engine, by managing the input and output transfers,
and calling the defined callback function when required.

Notes

There are two options to use the USB driver:
1) Without interrupts by frequently calling 'usb_serial_flush()'
frequently in the main loop.
2) Using interrupts to make timing less critical. In that case no
calls to 'usb_serial_flush()' are needed.
This can be activated by defining: const USB_INTERRUPT_DRIVEN = TRUE
Do not use the interrupt driven feature when debugging the driver.

USB_PULLUP_OPTION, defines the USB PULL UP configuration
value can be set to USB_PULLUP_ENABLE to enable the USB pull up resistors
value can be set to USB_PULLUP_DISABLE to disable the USB pull up resistors

Sources

http://www.usb.org ; for USB specifications
http://www.lvr.com/usbc.htm ; a lot of information about USB
http://www.beyondlogic.org/ ; also a nice with with useful information

Constants and Variables

USB_PULLUP_OPTION - const byte = USB_PULLUP_ENABLE
USB_TRANSCEIVER_OPTION - const byte = USB_INTERNAL_TRANSCEIVER
USB_SPEED_OPTION - const byte = USB_FULL_SPEED

Routines

  • _usb_handle_reset - Procedure
  • _usb_handle_standard_request - Procedure
  • _usb_handle_transaction - Procedure
  • _usb_ints_on - Procedure
  • usb_enable_module - Procedure
  • usb_get_state - Function returns byte
  • usb_handle_isr - Procedure
  • usb_handle_stall - Procedure
  • usb_is_configured - Function returns bit
  • usb_setup - Procedure


usb_drv_cdc_class.jal - JALLIB Library Documentation

usb_drv_cdc_class.jal JALLIB LIBRARY

Title

USB Communication Device Class driver

Author

Albert Faber, Copyright (c) 2008..2021, all rights reserved., Adapted-by: Matthew Schinkel, Rob Jansen

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

USB Communication Device Class (CDC) code
This USB library files contains the low level implementation to perform serial
communication over a USB interface. The usage of this library requires detailed
knowledge of the USB interface and requires that several configuration parameters
are defined correctly. In order to make USB serial communication more accessible
for the end user, I would highly recommend to use the usb_serial library
--

Notes

------------------------------------------------------
------------------------------------------------------

Sources

http://www.usb.org for USB specifications

Constants and Variables

USB_CDC_DEBUG - const bit = false
USB_REQ_SEND_ENCAPSULATED_COMMAND - const byte = 0x00
USB_REQ_GET_ENCAPSULATED_RESPONSE - const byte = 0x01
USB_REQ_SET_COMM_FEATURE - const byte = 0x02
USB_REQ_CLEAR_COMM_FEATURE - const byte = 0x04
USB_REQ_SET_LINE_CODING - const byte = 0x20
USB_REQ_GET_LINE_CODING - const byte = 0x21
USB_REQ_SET_CONTROL_LINE_STATE - const byte = 0x22
USB_REQ_SEND_BREAK - const byte = 0x23
cdc_line_status - var byte = 0x00
last_packet_is_full - var bit = false

Routines

  • usb_cdc_getc - Function returns byte
  • usb_cdc_handle_tx - Procedure
  • usb_cdc_line_status - Function returns byte
  • usb_cdc_putc - Procedure
  • usb_cdc_rx_avail - Function returns bit
  • usb_cdc_setup - Procedure
  • usb_cdc_tx_empty - Function returns byte
  • usb_ep_data_in_callback - Procedure
  • usb_ep_data_out_callback - Procedure
  • usb_handle_class_ctrl_read_callback - Procedure
  • usb_handle_class_ctrl_write_callback - Procedure
  • usb_handle_class_request_callback - Procedure
  • usb_sof_callback - Procedure


usb_drv_core.jal - JALLIB Library Documentation

usb_drv_core.jal JALLIB LIBRARY

Title

USB driver library

Author

Albert Faber, Copyright (c) 2008..2021, all rights reserved., Adapted-by: Matthew Schinkel, Rob Jansen

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Routines for controlling the USB serial interface engine sending
which will ensure the highest possible accuracy.
--

Sources

http://www.usb.org for USB specifications

Routines

  • _usb_copy_array_to_ram - Procedure
  • usb_configure_endpoints - Procedure
  • usb_prime_ep0_out - Procedure
  • usb_prime_epx_out - Procedure
  • usb_send_data - Procedure
  • usb_send_data_chunk - Procedure
  • usb_send_empty_data_pkt - Procedure
  • usb_send_one_byte - Procedure
  • usb_send_status_ack - Procedure
  • usb_stall_ep0 - Procedure


usb_enable_module - JALlib Procedures Help

usb_enable_module JALLIB PROCEDURE

Signature

procedure usb_enable_module() is

Description

Procedure to turn on the USB device

Include

To use this procedure, include the library:

include usb_drv

Parameters

None

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_drv.jal


usb_ep_data_in_callback - JALlib Procedures Help

usb_ep_data_in_callback JALLIB PROCEDURE

Signature

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte in byte_count) is

Description

This function is called when data can be transmitted via the bulk interface
Data IN means that the device is sending data to the Host.
Note: Only the parameter end_point is used.

Include

To use this procedure, include the library:

include usb_drv_cdc_class

Parameters

  • end_point - byte in
  • buffer_addr - word in
  • byte_count - byte in

Return Value

None

Example

From sample file: 18f2550_usb_hid_mouse.jal

-- Title: USB HID device demo
-- Author: Albert Faber, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse pointing USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID is recognized by
-- the host operating systems, it will move around the mouse pointer
-- --
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: compiled with following flags
-- -loader18 -no-fuse
-- use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- ------------------------------------------------------
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_hid_mouse.jal
--

;@jallib section board_description

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

include delay

;@jallib section serial

-- whether or not using the serial port
const HAS_SERIAL_DEBUG_PORT = 1

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

  -- uncomment when directly coupled (i.e. without max 232) to rs-232C
  -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure
end if

const bit USB_DEBUG = false
const bit USB_DEBUG_HIGH = false
const bit USB_HID_DEBUG = false
const bit USB_HID_DEBUG_HIGH = false
const byte USB_HID_ENDPOINT = 0x01
var volatile bit usb_hid_can_tx = true

include usb_defs

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 8
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = 8
const word USB_EP1_IN_ADDR  = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )

var volatile byte  usb_ep1in_buf[ 8 ] at USB_EP1_IN_ADDR

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    0x08,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x00,
    0x00,		-- Mouse circle demo
    0x02,
    0x00, 	     -- version 2.0 of the product
    0x01,		-- string 1 for manufacturer
    0x02,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x09 + 0x07

const byte USB_HID_REPORT1[]=
{
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x02, -- Usage (Mouse)
    0xA1, 0x01, -- Collection (Application)
    0x09, 0x01, -- Usage (Pointer)
    0xA1, 0x00, -- Collection (Physical)
    0x05, 0x09, -- Usage Page (Buttons)
    0x19, 0x01, -- Usage Minimum (01)
    0x29, 0x03, -- Usage Maximum (03)
    0x15, 0x00, -- Logical Minimum (0)
    0x25, 0x01, -- Logical Maximum (0)
    0x95, 0x03, -- Report Count (3)
    0x75, 0x01, -- Report Size (1)
    0x81, 0x02, -- Input (Data, Variable, Absolute)
    0x95, 0x01, -- Report Count (1)
    0x75, 0x05, -- Report Size (5)
    0x81, 0x01, -- Input (Constant), 5 bit padding
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x30, -- Usage (X)
    0x09, 0x31, -- Usage (Y)
    0x15, 0x81, -- Logical Minimum (-127)
    0x25, 0x7F, -- Logical Maximum (127)
    0x75, 0x08, -- Report Size (8)
    0x95, 0x02, -- Report Count (2)
    0x81, 0x06, -- Input (Data, Variable, Relative)
    0xC0, 0xC0
}

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,	-- length,
    USB_DT_INTERFACE,	-- descriptor_type,
    0x00,	-- interface_number, (starts at zero)
    0x00,	-- alternate_setting, (no alternatives)
    0x01,	-- num_endpoints,
    0x03,	-- interface_class, (HID)
    0x01,	-- interface_subclass, (boot - is this necessary?)
    0x02,	-- interface_protocol, (mouse)
    0x00,	-- interface_string_id;

    -- hid descriptor - - - - - - - - - - - - - - -
    0x09,				-- length,
    USB_DT_HID,			-- descriptor_type;
    0x11,
    0x01,				-- hid_spec in BCD (1.11)
    0x00,				-- country_code, (0=not country specific)
    0x01,				-- num_class_descriptors, (1)
    USB_DT_HID_REPORT,	-- class_descriptor_type; (0x22 = report)
    (count( USB_HID_REPORT1 ) & 0xFF ),
    (count( USB_HID_REPORT1 ) >> 8 ),

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    0b00000011,			-- attributes; (Interrupt)
    0x03,
    0x00,				-- max_packet_size
    0x0A				-- interval (10ms)
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

const byte USB_STRING1[] =
{
    0x36,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "M", 0x00,
    "i", 0x00,
    "c", 0x00,
    "r", 0x00,
    "o", 0x00,
    "c", 0x00,
    "h", 0x00,
    "i", 0x00,
    "p", 0x00,
    " ", 0x00,
    "T", 0x00,
    "e", 0x00,
    "c", 0x00,
    "h", 0x00,
    "n", 0x00,
    "o", 0x00,
    "l", 0x00,
    "o", 0x00,
    "g", 0x00,
    "y", 0x00,
    ",", 0x00,
    " ", 0x00,
    "I", 0x00,
    "n", 0x00,
    "c", 0x00,
    ".", 0x00
}

const byte USB_STRING2[44] =
{
    44,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    " ", 0x00,
    "H", 0x00,
    "I", 0x00,
    "D", 0x00,
    " ", 0x00,
    "M", 0x00,
    "o", 0x00,
    "u", 0x00,
    "s", 0x00,
    "e", 0x00,
    " ", 0x00,
    "D", 0x00,
    "e", 0x00,
    "m", 0x00,
    "o", 0x00
}

include usb_drv_core

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte  in byte_count) is
    pragma inline
    if USB_HID_DEBUG_HIGH then
        const byte str[] = " EP data in: "
        const byte str1[] = " bytes "
        print_string( serial_hw_data,str )
        print_byte_hex( serial_hw_data, byte_count & 0xFF)
        print_string(serial_hw_data,str1)
    end if

    -- data has been sent, so do we need to send more?
    if (end_point == USB_HID_ENDPOINT) then
        -- it's the data end point
        usb_hid_can_tx = true
    end if
end procedure

include usb_drv

-- constants
const sbyte dir_table[] = {-4,-4,-4, 0, 4, 4, 4, 0}
const  byte str_welcome[] = "JALLIB USB HID MOUSE DEMO version 1.0\nplease wait (takes ~10 seconds) before the device it is fully configured"

-- variables
var word i = 0
var byte movement_length
var byte vector = 0
var bit usb_initialized = false
var byte data_buffer[3]
var word ticks100us = 0
var bit enable_mouse = false

procedure usb_tasks() is
    -- Servicing Hardware
    -- use polling method
    usb_handle_isr()
end procedure

-- interrupts? No thanks
while INTCON_GIE loop
    INTCON_GIE = false
end loop

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

-- setup the USB device
usb_setup()

-- enable USB device
usb_enable_module()

-- initialize HID buffer
data_buffer[0] = 0x00
data_buffer[1] = 0x00
data_buffer[2] = 0x00

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_tasks()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

        -- note user via serial line that USB has been configured
        if usb_initialized == false then
            usb_initialized = true

            if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                const  byte str[] = "USB device has been configured by the HOST!"
                print_string(serial_hw_data, str )
                serial_newline()
            end if
        end if

        -- now the mouse pointer can be moved around
        enable_mouse = true
    end if

    if enable_mouse then
        ticks100us = ticks100us + 1
        delay_10us(10)

        if ticks100us == 250 then
            ticks100us = 0

            if( movement_length > 16 ) then
                data_buffer[0] = 0
                data_buffer[1] = byte( dir_table[vector & 0x07] ) -- X-Vector
                data_buffer[2] = byte( dir_table[(vector+2) & 0x07] ) -- Y-Vector
                vector = vector+1
                movement_length = 0
            end if

            if 	( usb_hid_can_tx ) then
                usb_hid_can_tx = false
                usb_send_data(1, data_buffer, 3, low )
                movement_length =  movement_length + 1
            end if

        end if
    end if

    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
            serial_hw_write( RCREG )

            if RCREG == "S" then
            end if
            if RCREG == "T" then
            end if
        end if
    end if

end loop

Generated by JALlib CHM Help System | Source: usb_drv_cdc_class.jal


usb_ep_data_out_callback - JALlib Procedures Help

usb_ep_data_out_callback JALLIB PROCEDURE

Signature

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is

Description

This function is called when data can be received via the bulk interface
Data in means that the Host is sending data to the device.

Include

To use this procedure, include the library:

include usb_drv_cdc_class

Parameters

  • end_point - byte in
  • buffer_addr - word in
  • byte_count - byte in

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_drv_cdc_class.jal


usb_handle_isr - JALlib Procedures Help

usb_handle_isr JALLIB PROCEDURE

Signature

procedure usb_handle_isr() is

Description

This is the heart of the USB library, all pending IO transfers are handled by
this main (interrupt) service routine. The routine can be used interrupt based
or by polling.
When using interrupt, it will occur at least once ever 1 ms since the Start Of
Frame (SOF) package is sent every 1 ms by the Host.

Include

To use this procedure, include the library:

include usb_drv

Parameters

None

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_drv.jal


usb_is_configured - JALlib Procedures Help

usb_is_configured JALLIB FUNCTION

Signature

function usb_is_configured() return bit is

Description

Function returns true if the usb device has been completely configured, otherwise
return value will be false

Include

To use this procedure, include the library:

include usb_drv

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 18f2550_usb_hid_mouse.jal

-- Title: USB HID device demo
-- Author: Albert Faber, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse pointing USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID is recognized by
-- the host operating systems, it will move around the mouse pointer
-- --
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: compiled with following flags
-- -loader18 -no-fuse
-- use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- ------------------------------------------------------
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_hid_mouse.jal
--

;@jallib section board_description

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

include delay

;@jallib section serial

-- whether or not using the serial port
const HAS_SERIAL_DEBUG_PORT = 1

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

  -- uncomment when directly coupled (i.e. without max 232) to rs-232C
  -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure
end if

const bit USB_DEBUG = false
const bit USB_DEBUG_HIGH = false
const bit USB_HID_DEBUG = false
const bit USB_HID_DEBUG_HIGH = false
const byte USB_HID_ENDPOINT = 0x01
var volatile bit usb_hid_can_tx = true

include usb_defs

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 8
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = 8
const word USB_EP1_IN_ADDR  = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )

var volatile byte  usb_ep1in_buf[ 8 ] at USB_EP1_IN_ADDR

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    0x08,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x00,
    0x00,		-- Mouse circle demo
    0x02,
    0x00, 	     -- version 2.0 of the product
    0x01,		-- string 1 for manufacturer
    0x02,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x09 + 0x07

const byte USB_HID_REPORT1[]=
{
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x02, -- Usage (Mouse)
    0xA1, 0x01, -- Collection (Application)
    0x09, 0x01, -- Usage (Pointer)
    0xA1, 0x00, -- Collection (Physical)
    0x05, 0x09, -- Usage Page (Buttons)
    0x19, 0x01, -- Usage Minimum (01)
    0x29, 0x03, -- Usage Maximum (03)
    0x15, 0x00, -- Logical Minimum (0)
    0x25, 0x01, -- Logical Maximum (0)
    0x95, 0x03, -- Report Count (3)
    0x75, 0x01, -- Report Size (1)
    0x81, 0x02, -- Input (Data, Variable, Absolute)
    0x95, 0x01, -- Report Count (1)
    0x75, 0x05, -- Report Size (5)
    0x81, 0x01, -- Input (Constant), 5 bit padding
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x30, -- Usage (X)
    0x09, 0x31, -- Usage (Y)
    0x15, 0x81, -- Logical Minimum (-127)
    0x25, 0x7F, -- Logical Maximum (127)
    0x75, 0x08, -- Report Size (8)
    0x95, 0x02, -- Report Count (2)
    0x81, 0x06, -- Input (Data, Variable, Relative)
    0xC0, 0xC0
}

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,	-- length,
    USB_DT_INTERFACE,	-- descriptor_type,
    0x00,	-- interface_number, (starts at zero)
    0x00,	-- alternate_setting, (no alternatives)
    0x01,	-- num_endpoints,
    0x03,	-- interface_class, (HID)
    0x01,	-- interface_subclass, (boot - is this necessary?)
    0x02,	-- interface_protocol, (mouse)
    0x00,	-- interface_string_id;

    -- hid descriptor - - - - - - - - - - - - - - -
    0x09,				-- length,
    USB_DT_HID,			-- descriptor_type;
    0x11,
    0x01,				-- hid_spec in BCD (1.11)
    0x00,				-- country_code, (0=not country specific)
    0x01,				-- num_class_descriptors, (1)
    USB_DT_HID_REPORT,	-- class_descriptor_type; (0x22 = report)
    (count( USB_HID_REPORT1 ) & 0xFF ),
    (count( USB_HID_REPORT1 ) >> 8 ),

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    0b00000011,			-- attributes; (Interrupt)
    0x03,
    0x00,				-- max_packet_size
    0x0A				-- interval (10ms)
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

const byte USB_STRING1[] =
{
    0x36,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "M", 0x00,
    "i", 0x00,
    "c", 0x00,
    "r", 0x00,
    "o", 0x00,
    "c", 0x00,
    "h", 0x00,
    "i", 0x00,
    "p", 0x00,
    " ", 0x00,
    "T", 0x00,
    "e", 0x00,
    "c", 0x00,
    "h", 0x00,
    "n", 0x00,
    "o", 0x00,
    "l", 0x00,
    "o", 0x00,
    "g", 0x00,
    "y", 0x00,
    ",", 0x00,
    " ", 0x00,
    "I", 0x00,
    "n", 0x00,
    "c", 0x00,
    ".", 0x00
}

const byte USB_STRING2[44] =
{
    44,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    " ", 0x00,
    "H", 0x00,
    "I", 0x00,
    "D", 0x00,
    " ", 0x00,
    "M", 0x00,
    "o", 0x00,
    "u", 0x00,
    "s", 0x00,
    "e", 0x00,
    " ", 0x00,
    "D", 0x00,
    "e", 0x00,
    "m", 0x00,
    "o", 0x00
}

include usb_drv_core

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte  in byte_count) is
    pragma inline
    if USB_HID_DEBUG_HIGH then
        const byte str[] = " EP data in: "
        const byte str1[] = " bytes "
        print_string( serial_hw_data,str )
        print_byte_hex( serial_hw_data, byte_count & 0xFF)
        print_string(serial_hw_data,str1)
    end if

    -- data has been sent, so do we need to send more?
    if (end_point == USB_HID_ENDPOINT) then
        -- it's the data end point
        usb_hid_can_tx = true
    end if
end procedure

include usb_drv

-- constants
const sbyte dir_table[] = {-4,-4,-4, 0, 4, 4, 4, 0}
const  byte str_welcome[] = "JALLIB USB HID MOUSE DEMO version 1.0\nplease wait (takes ~10 seconds) before the device it is fully configured"

-- variables
var word i = 0
var byte movement_length
var byte vector = 0
var bit usb_initialized = false
var byte data_buffer[3]
var word ticks100us = 0
var bit enable_mouse = false

procedure usb_tasks() is
    -- Servicing Hardware
    -- use polling method
    usb_handle_isr()
end procedure

-- interrupts? No thanks
while INTCON_GIE loop
    INTCON_GIE = false
end loop

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

-- setup the USB device
usb_setup()

-- enable USB device
usb_enable_module()

-- initialize HID buffer
data_buffer[0] = 0x00
data_buffer[1] = 0x00
data_buffer[2] = 0x00

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_tasks()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

        -- note user via serial line that USB has been configured
        if usb_initialized == false then
            usb_initialized = true

            if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                const  byte str[] = "USB device has been configured by the HOST!"
                print_string(serial_hw_data, str )
                serial_newline()
            end if
        end if

        -- now the mouse pointer can be moved around
        enable_mouse = true
    end if

    if enable_mouse then
        ticks100us = ticks100us + 1
        delay_10us(10)

        if ticks100us == 250 then
            ticks100us = 0

            if( movement_length > 16 ) then
                data_buffer[0] = 0
                data_buffer[1] = byte( dir_table[vector & 0x07] ) -- X-Vector
                data_buffer[2] = byte( dir_table[(vector+2) & 0x07] ) -- Y-Vector
                vector = vector+1
                movement_length = 0
            end if

            if 	( usb_hid_can_tx ) then
                usb_hid_can_tx = false
                usb_send_data(1, data_buffer, 3, low )
                movement_length =  movement_length + 1
            end if

        end if
    end if

    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
            serial_hw_write( RCREG )

            if RCREG == "S" then
            end if
            if RCREG == "T" then
            end if
        end if
    end if

end loop

Generated by JALlib CHM Help System | Source: usb_drv.jal


usb_keyboard.jal - JALLIB Library Documentation

usb_keyboard.jal JALLIB LIBRARY

Title

USB HID easy keyboard interface

Author

Albert Faber, Copyright (c) 2010..2021, all rights reserved., Adapted-by: Joep Suijs, Rob Jansen

Compiler

2.5r4

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

An easy to use USB HID keyboard library
the USB interface. By default nothing has to be defined by the user, below
an example how to use the library
--
include usb_keyboard
..
usb_keyboard_init()
..
;-- wait till USB becomes available
while ( !usb_is_configured() ) loop
end loop
..
;-- main loop
var byte ch
forever loop
; -- call the flush routine on a regular base in the main loop
; -- in order to keep the USB communicaiton alive
; -- This is only needed when USB_INTERRUPT_DRIVEN is not defined, otherwise
; -- the usb_serial_flush() is not needed, see notes.
;
usb_keyboard_flush()
.....
if ( usb_is_configured() )
if ( pin_x )
ush_keyboard_send_key( 0x00, USB_KEYBOARD_KEY_A )
else
ush_keyboard_send_key( 0x00, USB_KEYBOARD_KEY_NONE )
end if
.....
end loop

Notes

There are two options to use the USB driver for keyboard:
1) Without interrupts by frequently calling 'usb_keyboard_flush()'
frequently in the main loop.
2) Using interrupts to make timing less critical. In that case no
calls to 'usb_keyboard_flush()' are needed.
This can be activated by defining: const USB_INTERRUPT_DRIVEN = TRUE

Sources

http://www.usb.org for USB specifications

Constants and Variables

USB_HID_ENDPOINT - const byte = 0x01
USB_DEBUG - const bit = true
USB_DEBUG_HIGH - const bit = false
USB_HID_DEBUG - const bit = false
USB_HID_DEBUG_HIGH - const bit = false
USB_DEBUG - const bit = false
USB_DEBUG_HIGH - const bit = false
USB_HID_DEBUG - const bit = false
USB_HID_DEBUG_HIGH - const bit = false
USB_EP0 - const bit = 1
USB_EP0_OUT_SIZE - const byte = 8
USB_EP0_OUT_ADDR - const word = ( USB_BASE_ADDRESS + 0x0010 )
USB_EP0_IN_SIZE - const byte = 8
USB_EP0_IN_ADDR - const word = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )
USB_EP1 - const bit = 1
USB_EP1_OUT_SIZE - const byte = 8
USB_EP1_OUT_ADDR - const word = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
USB_EP1_IN_SIZE - const byte = 8
USB_EP1_IN_ADDR - const word = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )
USB_EP2 - const bit = 0
USB_EP2_OUT_SIZE - const byte = 8
USB_EP2_OUT_ADDR - const word = 0x0000
USB_EP2_IN_SIZE - const byte = 8
USB_EP2_IN_ADDR - const word = 0x0000
USB_EP3 - const bit = 0
USB_EP3_OUT_SIZE - const byte = 8
USB_EP3_OUT_ADDR - const word = 0x0000
USB_EP3_IN_SIZE - const byte = 8
USB_EP3_IN_ADDR - const word = 0x0000
USB_HID_REQ_HID - const byte = 0x21
USB_HID_REQ_REPORT - const byte = 0x22
USB_HID_REQ_PHYSDISCR - const byte = 0x23
USB_HCR_GET_REPORT - const byte = 0x01
USB_HCR_GET_IDLE - const byte = 0x02
USB_HCR_GET_PROTOCOL - const byte = 0x03
USB_HCR_SET_REPORT - const byte = 0x09
USB_HCR_SET_IDLE - const byte = 0x0A
USB_HCR_SET_PROTOCOL - const byte = 0x0B
ASCII_USB_CTRL - const byte = 0x40
ASCII_USB_SHIFT - const byte = 0x80

Routines

  • _usb_hid_tx_report - Procedure
  • serial_newline - Procedure
  • serial_print_spc - Procedure
  • usb_ep_data_in_callback - Procedure
  • usb_handle_class_ctrl_read_callback - Procedure
  • usb_handle_class_ctrl_write_callback - Procedure
  • usb_handle_class_request_callback - Procedure
  • usb_keyboard_flush - Procedure
  • usb_keyboard_init - Procedure
  • usb_keyboard_led_caps_lock'get - Function returns bit
  • usb_keyboard_led_compose'get - Function returns bit
  • usb_keyboard_led_kana'get - Function returns bit
  • usb_keyboard_led_num_lock'get - Function returns bit
  • ush_keyboard_send_ascii - Procedure
  • ush_keyboard_send_key - Procedure


usb_keyboard_flush - JALlib Procedures Help

usb_keyboard_flush JALLIB PROCEDURE

Signature

procedure usb_keyboard_flush() is

Description

usb_keyboard_flush shall be called on a regular base (millisecond range)
in order to keep the USB communcation alive. Therfore it is adviced to
call the usb_keyboard _flush procedure in the main loop of your
application.
Note: Only needed when USB interrupt is not used otherwise this call
can be omitted (it does nothing in interrupt mode).

Include

To use this procedure, include the library:

include usb_keyboard

Parameters

None

Return Value

None

Example

From sample file: 16f1455_usb_hid_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: USB HID keyboard device demo for the PIC16F1455
-- Author: Rob Jansen, Copyright (c) 2018..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a keyboard USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID device is recognized by
-- the host operating systems, it will generate keyboard chars if boot program pin is low
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: There are two options to use the USB driver:
--        1) Without interrupts by frequently calling 'usb_keyboard_flush()'
--           frequently in the main loop.
--        2) Using interrupts to make timing less critical. In that case no
--           calls to 'usb_keyboard_flush()' are needed.
--           This can be activated by defining: const USB_INTERRUPT_DRIVEN = TRUE
--
-- ------------------------------------------------------
--
-- This file was orginally copied from 18f14k50_hid_keyboard.jal and made
-- operational to work for the PIC16F1454/55/59 using the modified usb driver.
--

include 16f1455

-- For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
-- the USB connection and connected as follows:
-- *) USB data- wire to pin 12 (D-)
-- *) USB data+ wire to pin 13 (D+)
-- *) USB power wire to pin 1 (Vdd). Don't forget 100nF decoupling capacitor.
-- *) USB ground wire to pin 14 (Vss)
-- *) A resistor of 33kOhm to pin 4 (MCLR) and power. We use internal reset.
-- *) A capacitor of 220nF to pin 11 (Vusb3v3) and ground.
-- *) A crystal of 12 MHz to pin 2 and pin 3 with 2*18 pF capacitors to ground.
-- Settings are also given to use the internal oscilator of the PIC so no need
-- for the 12 MHz crystal which saves you a crystal and 2 pins on the chip.
-- The configuration runs at an internal clock of 48 MHz.
-- Two additional indication LEDs are connected, see definition below.

pragma target clock       48_000_000

-- Compiler options.
pragma warn all no              -- We do not want to know all compiler warnings
pragma opt variable_reduce yes

-- fuses
-- Settings for external 12 MHz crystal and system clock 48 MHz.
pragma target OSC           HS       -- External crystal
pragma target CLKOUTEN      ENABLED  -- CLKOUT function is enabled
pragma target PLLMULT       N4X      -- PLL Multipler Selection Bit, 4x Output Frequency Selected

-- Settings for internal clock and system clock 48 MHz.
--pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
--pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
--pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- Exyzabternal reset
pragma target LVP           DISABLED -- no low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1000          -- Weak-pull up for relevant port a bits.

include delay

-- Pin definitions.
alias bootloader_program_pin is pin_c2  -- Pin 8.
alias bootloader_program_pin_direction  is pin_c2_direction

-- LED IO definition
alias led             is pin_c3         -- Pin 7.
alias led_direction   is pin_c3_direction
alias led2            is pin_c4         -- Pin 6.
alias led2_direction  is pin_c4_direction

-- Use the USB driver on an interrupt basis. This makes it possible to use
-- delays in the main loop since timing becomes less critical.
const USB_INTERRUPT_DRIVEN = TRUE
include usb_keyboard

-- set all inputs to digital
enable_digital_io()

-- setup direction bits
led_direction = output
led2_direction = output
bootloader_program_pin_direction = input

var byte key_value = USB_KEYBOARD_KEY_A

-- intialize the library
usb_keyboard_init()

-- main loop
forever loop

   if !defined(USB_INTERRUPT_DRIVEN) then
      -- When the interrupt mode is not used we need to poll the usb ISR function
      -- on a regular base, in order to serve the USB requests otherwise
      -- this call can be removed.
      usb_keyboard_flush()
   end if

   -- check if USB device has been configured by the HOST
   if usb_is_configured()  then

      led = usb_keyboard_led_caps_lock
      led2 = usb_keyboard_led_num_lock

      if ( bootloader_program_pin == low )then
      -- send key code towards the USB host
      -- ush_keyboard_send_key( USB_KEYBOARD_MKEY_LEFT_SHIFT, key_value )
      ush_keyboard_send_key( 0x00, key_value )

      -- next key code
      key_value = key_value + 1
      if ( key_value > USB_KEYBOARD_KEY_Z ) then
         key_value = USB_KEYBOARD_KEY_A
      end if
   else
      -- depress key
      ush_keyboard_send_key( 0, 0 )
   end if

      -- debounce switch
      delay_1ms(50)
   end if

end loop

Generated by JALlib CHM Help System | Source: usb_keyboard.jal


usb_keyboard_init - JALlib Procedures Help

usb_keyboard_init JALLIB PROCEDURE

Signature

procedure usb_keyboard_init() is

Description

usb_keyboard_init will setup the HID USB communication with the HOST,
however, this can be a time consuming process, therefore this call
is non blocking. In order to check if communication with the HOST
has been established, one can call the usb_is_configured() function, see
usb_is_configured() documentation for additional details.

Include

To use this procedure, include the library:

include usb_keyboard

Parameters

None

Return Value

None

Example

From sample file: 16f1455_usb_hid_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: USB HID keyboard device demo for the PIC16F1455
-- Author: Rob Jansen, Copyright (c) 2018..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a keyboard USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID device is recognized by
-- the host operating systems, it will generate keyboard chars if boot program pin is low
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: There are two options to use the USB driver:
--        1) Without interrupts by frequently calling 'usb_keyboard_flush()'
--           frequently in the main loop.
--        2) Using interrupts to make timing less critical. In that case no
--           calls to 'usb_keyboard_flush()' are needed.
--           This can be activated by defining: const USB_INTERRUPT_DRIVEN = TRUE
--
-- ------------------------------------------------------
--
-- This file was orginally copied from 18f14k50_hid_keyboard.jal and made
-- operational to work for the PIC16F1454/55/59 using the modified usb driver.
--

include 16f1455

-- For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
-- the USB connection and connected as follows:
-- *) USB data- wire to pin 12 (D-)
-- *) USB data+ wire to pin 13 (D+)
-- *) USB power wire to pin 1 (Vdd). Don't forget 100nF decoupling capacitor.
-- *) USB ground wire to pin 14 (Vss)
-- *) A resistor of 33kOhm to pin 4 (MCLR) and power. We use internal reset.
-- *) A capacitor of 220nF to pin 11 (Vusb3v3) and ground.
-- *) A crystal of 12 MHz to pin 2 and pin 3 with 2*18 pF capacitors to ground.
-- Settings are also given to use the internal oscilator of the PIC so no need
-- for the 12 MHz crystal which saves you a crystal and 2 pins on the chip.
-- The configuration runs at an internal clock of 48 MHz.
-- Two additional indication LEDs are connected, see definition below.

pragma target clock       48_000_000

-- Compiler options.
pragma warn all no              -- We do not want to know all compiler warnings
pragma opt variable_reduce yes

-- fuses
-- Settings for external 12 MHz crystal and system clock 48 MHz.
pragma target OSC           HS       -- External crystal
pragma target CLKOUTEN      ENABLED  -- CLKOUT function is enabled
pragma target PLLMULT       N4X      -- PLL Multipler Selection Bit, 4x Output Frequency Selected

-- Settings for internal clock and system clock 48 MHz.
--pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
--pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
--pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- Exyzabternal reset
pragma target LVP           DISABLED -- no low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1000          -- Weak-pull up for relevant port a bits.

include delay

-- Pin definitions.
alias bootloader_program_pin is pin_c2  -- Pin 8.
alias bootloader_program_pin_direction  is pin_c2_direction

-- LED IO definition
alias led             is pin_c3         -- Pin 7.
alias led_direction   is pin_c3_direction
alias led2            is pin_c4         -- Pin 6.
alias led2_direction  is pin_c4_direction

-- Use the USB driver on an interrupt basis. This makes it possible to use
-- delays in the main loop since timing becomes less critical.
const USB_INTERRUPT_DRIVEN = TRUE
include usb_keyboard

-- set all inputs to digital
enable_digital_io()

-- setup direction bits
led_direction = output
led2_direction = output
bootloader_program_pin_direction = input

var byte key_value = USB_KEYBOARD_KEY_A

-- intialize the library
usb_keyboard_init()

-- main loop
forever loop

   if !defined(USB_INTERRUPT_DRIVEN) then
      -- When the interrupt mode is not used we need to poll the usb ISR function
      -- on a regular base, in order to serve the USB requests otherwise
      -- this call can be removed.
      usb_keyboard_flush()
   end if

   -- check if USB device has been configured by the HOST
   if usb_is_configured()  then

      led = usb_keyboard_led_caps_lock
      led2 = usb_keyboard_led_num_lock

      if ( bootloader_program_pin == low )then
      -- send key code towards the USB host
      -- ush_keyboard_send_key( USB_KEYBOARD_MKEY_LEFT_SHIFT, key_value )
      ush_keyboard_send_key( 0x00, key_value )

      -- next key code
      key_value = key_value + 1
      if ( key_value > USB_KEYBOARD_KEY_Z ) then
         key_value = USB_KEYBOARD_KEY_A
      end if
   else
      -- depress key
      ush_keyboard_send_key( 0, 0 )
   end if

      -- debounce switch
      delay_1ms(50)
   end if

end loop

Generated by JALlib CHM Help System | Source: usb_keyboard.jal


usb_mouse.jal - JALLIB Library Documentation

usb_mouse.jal JALLIB LIBRARY

Title

USB HID mouse device demo

Author

Matthew Schinkel

Compiler

>=2.5r4

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

This application emulates a mouse USB human interface device
(HID), once the USB device has been configured and the USB HID device is recognized by
the host operating systems, it will move the computer mouse.

Sources

Albert Faber& Joep Suijs jallib usb_keyboard library
https://www.silabs.com/documents/public/application-notes/AN249.pdf

Constants and Variables

USB_HID_ENDPOINT - const byte = 0x01
USB_DEBUG - const bit = true
USB_DEBUG_HIGH - const bit = false
USB_HID_DEBUG - const bit = false
USB_HID_DEBUG_HIGH - const bit = false
USB_DEBUG - const bit = false
USB_DEBUG_HIGH - const bit = false
USB_HID_DEBUG - const bit = false
USB_HID_DEBUG_HIGH - const bit = false
USB_EP0 - const bit = 1
USB_EP0_OUT_SIZE - const byte = 8
USB_EP0_OUT_ADDR - const word = ( USB_BASE_ADDRESS + 0x0010 )
USB_EP0_IN_SIZE - const byte = 8
USB_EP0_IN_ADDR - const word = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )
USB_EP1 - const bit = 1
USB_EP1_OUT_SIZE - const byte = 4
USB_EP1_OUT_ADDR - const word = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
USB_EP1_IN_SIZE - const byte = 4
USB_EP1_IN_ADDR - const word = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )
USB_EP2 - const bit = 0
USB_EP2_OUT_SIZE - const byte = 8
USB_EP2_OUT_ADDR - const word = 0x0000
USB_EP2_IN_SIZE - const byte = 8
USB_EP2_IN_ADDR - const word = 0x0000
USB_EP3 - const bit = 0
USB_EP3_OUT_SIZE - const byte = 8
USB_EP3_OUT_ADDR - const word = 0x0000
USB_EP3_IN_SIZE - const byte = 8
USB_EP3_IN_ADDR - const word = 0x0000
USB_HID_REQ_HID - const byte = 0x21
USB_HID_REQ_REPORT - const byte = 0x22
USB_HID_REQ_PHYSDISCR - const byte = 0x23
USB_HCR_GET_REPORT - const byte = 0x01
USB_HCR_GET_IDLE - const byte = 0x02
USB_HCR_GET_PROTOCOL - const byte = 0x03
USB_HCR_SET_REPORT - const byte = 0x09
USB_HCR_SET_IDLE - const byte = 0x0A
USB_HCR_SET_PROTOCOL - const byte = 0x0B

Routines

  • _usb_hid_tx_report - Procedure
  • serial_newline - Procedure
  • serial_print_spc - Procedure
  • usb_ep_data_in_callback - Procedure
  • usb_handle_class_ctrl_read_callback - Procedure
  • usb_handle_class_ctrl_write_callback - Procedure
  • usb_handle_class_request_callback - Procedure
  • usb_mouse_flush - Procedure
  • usb_mouse_init - Procedure
  • usb_mouse_left_click - Procedure
  • usb_mouse_move - Procedure
  • usb_mouse_move_wheel - Procedure
  • usb_mouse_right_click - Procedure
  • usb_mouse_send_button - Procedure
  • usb_mouse_wheel_click - Procedure


usb_mouse_flush - JALlib Procedures Help

usb_mouse_flush JALLIB PROCEDURE

Signature

procedure usb_mouse_flush() is

Description

usb_mouse_flush shall be called on a regular base (millisecond range)
in order to keep the USB communcation alive. Therfore it is adviced to
call the usb_mouse _flush procedure in the main loop of your
application.
Note: Only needed when USB interrupt is not used otherwise this call
can be omitted (it does nothing in interrupt mode).

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_mouse_init - JALlib Procedures Help

usb_mouse_init JALLIB PROCEDURE

Signature

procedure usb_mouse_init() is

Description

usb_mouse_init will setup the HID USB communication with the HOST,
however, this can be a time consuming process, therefore this call
is non blocking. In order to check if communication with the HOST
has been established, one can call the usb_is_configured() function, see
usb_is_configured() documentation for additional details.

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_mouse_left_click - JALlib Procedures Help

usb_mouse_left_click JALLIB PROCEDURE

Signature

procedure usb_mouse_left_click() is

Description

mouse left click

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_mouse_move - JALlib Procedures Help

usb_mouse_move JALLIB PROCEDURE

Signature

procedure usb_mouse_move(sbyte in move_left_right, sbyte in move_up_down) is

Description

Move the mouse

Include

To use this procedure, include the library:

include usb_mouse

Parameters

  • move_left_right - sbyte in
  • move_up_down - sbyte in

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_mouse_move_wheel - JALlib Procedures Help

usb_mouse_move_wheel JALLIB PROCEDURE

Signature

procedure usb_mouse_move_wheel(sbyte in data) is

Description

Move the mouse

Include

To use this procedure, include the library:

include usb_mouse

Parameters

  • data - sbyte in

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_mouse_right_click - JALlib Procedures Help

usb_mouse_right_click JALLIB PROCEDURE

Signature

procedure usb_mouse_right_click() is

Description

mouse right click

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_mouse_wheel_click - JALlib Procedures Help

usb_mouse_wheel_click JALLIB PROCEDURE

Signature

procedure usb_mouse_wheel_click() is

Description

mouse wheel click

Include

To use this procedure, include the library:

include usb_mouse

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_mouse.jal

-- Title: USB HID mouse device demo
-- Author: Matthew Schinkel
-- Compiler: >=2.5r4
-- Revision: $Revision$
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse USB human interface device
-- (HID), once the USB device has been configured and the USB HID device is recognized by
-- the host operating systems, it will move the computer mouse.
--
-- Sources:
-- Albert Faber& Joep Suijs jallib usb_keyboard library
-- Albert Faber& Joep Suijs jallib usb_hid_mouse samples
-- https://www.silabs.com/documents/public/application-notes/AN249.pdf
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O

include delay

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
-- include print
const PRINT_MAX_VAR_SIZE = 6
include print
include format
--
print_string(serial_data,"Jallib Sample Started...")
print_crlf(serial_data)

-- include usb_mouse library
include usb_mouse

-- intialize the library
usb_mouse_init()

-- main loop
forever loop
    -- poll the usb flush function on a regular base, in order to
    -- serve the USB requests
    usb_mouse_flush()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

      ;usb_mouse_left_click()
      ;usb_mouse_right_click()
      ;usb_mouse_wheel_click()
      ;usb_mouse_move_wheel(5)  -- scroll up   (distance 5)
      ;usb_mouse_move_wheel(-5) -- scroll down (distance 5)

      for 10 loop
          usb_mouse_move(-5,0) -- move left (10 times, distance 5)
          serial_data = "<"
      end loop
      for 10 loop
          usb_mouse_move(0,-5) -- move up (10 times, distance 5)
          serial_data = "^"
      end loop
      for 10 loop
          usb_mouse_move(5,0) -- move right (10 times, distance 5)
          serial_data = ">"
      end loop
      for 10 loop
          usb_mouse_move(0,5) -- move down (10 times, distance 5)
          serial_data = "v"
      end loop
   else
      serial_data = "#"
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_mouse.jal


usb_msd.jal - JALLIB Library Documentation

usb_msd.jal JALLIB LIBRARY

Title

USB Mass Storage Device.

Author

Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved., Adapted-by:

Compiler

>=2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for USB MSD (Mass Storage Device) with SD card,
hard disk, or jallib supported storage device.

Sources

http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
http://direction.scene-double.com/2008/07/08/usb-msd-bootloader-for-pic-microcontrollers.aspx

Constants and Variables

USB_WRITE_SUPER_SPEED - const byte = 1 -- uses memory pointer for extra speed,
uses memory pointer for extra speed,
USB_WRITE_EXTRA_SPEED - const byte = 2 -- uses storage device extra speed routines,
uses storage device extra speed routines,
USB_WRITE_NORMAL_SPEED - const byte = 3 -- uses normal storage device routines
uses normal storage device routines
USB_WRITE_TRANSFER_SPEED - const byte = USB_WRITE_SUPER_SPEED
USB_WRITE_TRANSFER_SPEED - const byte = USB_WRITE_EXTRA_SPEED
USB_WRITE_TRANSFER_SPEED - const byte = USB_WRITE_NORMAL_SPEED
USB_WRITE_TRANSFER_SPEED - const byte = USB_WRITE_NORMAL_SPEED
USB_WRITE_TRANSFER_SPEED - const byte = USB_WRITE_NORMAL_SPEED
USB_READ_SUPER_SPEED - const byte = 1 -- uses memory pointer for extra speed,
uses memory pointer for extra speed,
USB_READ_EXTRA_SPEED - const byte = 2 -- uses storage device extra speed routines,
uses storage device extra speed routines,
USB_READ_NORMAL_SPEED - const byte = 3 -- uses normal storage device routines
uses normal storage device routines
USB_READ_TRANSFER_SPEED - const byte = USB_READ_SUPER_SPEED
USB_READ_TRANSFER_SPEED - const byte = USB_READ_EXTRA_SPEED
USB_READ_TRANSFER_SPEED - const byte = USB_READ_NORMAL_SPEED
USB_READ_TRANSFER_SPEED - const byte = USB_READ_NORMAL_SPEED
USB_READ_TRANSFER_SPEED - const byte = USB_READ_NORMAL_SPEED
usb_msd_sector_step_ - var dword
usb_msd_address - var dword
usb_msd_step64_ - var word = 0
usb_msd_step_byte_ - var byte = 0
usb_msd_state - var byte = USB_MSD_STATE_WAIT
usb_msd_num_of_blocks - var dword = storage_number_of_sectors
USB_MSD_CBW - const dword = 0x43425355 -- signature that helps identify data packet as a CBW
signature that helps identify data packet as a CBW
usb_msd_cbw_signature - var dword = 0 -- variable to receive a CBW signature before checking
variable to receive a CBW signature before checking
usb_msd_cbw_tag - var dword = 0 -- relat a SBW with a CSW at end of packet
relat a SBW with a CSW at end of packet
usb_msd_cbw_data_transfer_length - var dword = 0 -- # of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint 1
# of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint 1
usb_msd_csw_signature - var dword = 0 -- relate CSW with a SBW at the end of packet
relate CSW with a SBW at the end of packet
usb_msd_csw_tag - var dword = 0
usb_msd_data_residue - var dword = 0
usb_msd_csw_status - var byte = 0 -- status of the command excecuted
status of the command excecuted
USB_MSD_INQUIRY - const byte = 0x12
USB_MSD_READ_FORMAT_CAPACITY - const byte = 0x23
USB_MSD_READ_CAPACITY - const byte = 0x25
USB_MSD_READ_10 - const byte = 0x28
USB_MSD_WRITE_10 - const byte = 0x2a
USB_MSD_REQUEST_SENSE - const byte = 0x03
USB_MSD_MODE_SENSE - const byte = 0x1a
USB_MSD_PREVENT_ALLOW_MEDIUM_REMOVAL - const byte = 0x1e
USB_MSD_TEST_UNIT_READY - const byte = 0x00
USB_MSD_VERIFY - const byte = 0x2f
USB_MSD_STOP_START - const byte = 0x1b
usb_msd_sense_response_valid - var byte
usb_msd_sense_obsolete - var byte
usb_msd_sense_filemark_eom_ili_reserved_key - var byte
usb_msd_sense_information - var dword
usb_msd_sense_add_sense_len - var byte
usb_msd_sense_command_spacific - var dword
usb_msd_sense_asc - var byte
usb_msd_sense_ascq - var byte
usb_msd_sense_fruc - var byte
USB_MSD_SENSE_NOT_READY - const byte = 0x02
USB_MSD_SENSE_MEDIUM_ERROR - const byte = 0x03
USB_MSD_SENSE_ILLEGAL_REQUEST - const byte = 0x05
USB_MSD_SENSE_UNIT_ATTENTION - const byte = 0x06
USB_MSD_SENSE_ASC_LOGICAL_BLOCK_OUT_OF_RANGE - const byte = 0x21
USB_MSD_SENSE_ASCQ_LOGICAL_BLOCK_OUT_OF_RANGE - const byte = 0x00
USB_MSD_SENSE_ASC_MEDIUM_NOT_PRESENT - const byte = 0x3A
USB_MSD_SENSE_ASCQ_MEDIUM_NOT_PRESENT - const byte = 0x00
USB_MSD_SENSE_ASC_DEVICE_WRITE_FAULT - const byte = 0x03
USB_MSD_SENSE_ASCQ_DEVICE_WRITE_FAULT - const byte = 0x00
USB_MSD_SENSE_ASC_READ_ERROR - const byte = 0x11
USB_MSD_SENSE_ASCQ_READ_ERROR - const byte = 0x00
USB_MSD_SENSE_ASC_WRITE_PROTECTED - const byte = 0x27
USB_MSD_SENSE_ASCQ_WRITE_PROTECTED - const byte = 0x00
USB_MSD_SENSE_ASC_INVALID_COMMAND_OPCODE - const byte = 0x20
USB_MSD_SENSE_ASCQ_INVALID_COMMAND_OPCODE - const byte = 0x00
debug_data - var bit
DEBUG_MASTER_ENABLE - const bit = FALSE -- enables debugging
enables debugging
USB_EP0 - const bit = ENABLED
USB_EP0_OUT_SIZE - const byte = 64
USB_EP0_OUT_ADDR - const word = (USB_BASE_ADDRESS + 0x0010)
USB_EP0_IN_SIZE - const byte = 64
USB_EP0_IN_ADDR - const word = (USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )
USB_EP1 - const bit = ENABLED
USB_EP1_OUT_SIZE - const byte = 64
USB_EP1_OUT_ADDR - const word = (USB_EP0_IN_ADDR + USB_EP0_IN_SIZE)
USB_EP1_IN_SIZE - const byte = 64
USB_EP1_IN_ADDR - const word = (USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE) + 0x30
USB_EP2 - const bit = DISABLED
USB_EP3 - const bit = DISABLED
USB_STRING0_SIZE - const byte = 0x04
USB_STRING1_SIZE - const byte = 0x34
USB_STRING2_SIZE - const byte = 0x34
USB_STRING3_SIZE - const byte = 0x1A

Routines

  • msd_cbw_is_valid - Function returns bit
  • msd_send_data - Procedure
  • msd_wait_own_rx - Procedure
  • msd_wait_own_tx - Procedure
  • storage_read_callback - Procedure
  • storage_write_callback - Procedure
  • usb_ep_data_in_callback - Procedure
  • usb_ep_data_out_callback - Procedure
  • usb_handle_class_request_callback - Procedure
  • usb_msd_command_received - Procedure
  • usb_msd_init - Procedure
  • usb_msd_process_data - Procedure
  • usb_msd_read - Procedure
  • usb_msd_reset_sense_data - Procedure
  • usb_msd_tasks - Procedure
  • usb_msd_wait_configured - Procedure
  • usb_msd_write - Procedure
  • usb_print_speeds - Procedure
  • usb_read_callback - Procedure
  • usb_reset_callback - Procedure
  • usb_send_csw - Procedure
  • usb_write_callback - Procedure


usb_msd_init - JALlib Procedures Help

usb_msd_init JALLIB PROCEDURE

Signature

procedure usb_msd_init() is

Description

init procedure

Include

To use this procedure, include the library:

include usb_msd

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_msd_pata_hard_disk.jal

-- Title: USB Mass Storage Device Sample (pata hard disk)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program for USB MSD (Mass Storage Device) with pata hard disk.
--
--              Here are my speed tests:
--              Read Speed                               - 200KB/s
--              Write Speed                              - 180KB/s
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
-- http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
-- http://direction.scene-double.com/2008/07/08/usb-msd-bootloader-for-pic-microcontrollers.aspx
--
-- Notes:
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

include format

-- enable usb debugging
const bit USB_DEBUG = FALSE
const bit USB_DEBUG_HIGH = FALSE
;const bit USB_HID_DEBUG = TRUE
;const bit USB_HID_DEBUG_HIGH = TRUE

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = OFF    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_0 = ON  -- short debugging
debug_lvl_1 = OFF  -- display data in/out
debug_lvl_2 = OFF  -- display commands
debug_lvl_3 = OFF  -- short debug info
--
const byte debug_text0[] = "DEBUG STARTED"
debug_string(DEBUG_0,debug_text0)
debug_crlf(DEBUG_0)
--

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = TRUE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup MSD library
include usb_msd
usb_msd_init()
print_crlf(serial_data)
print_string(serial_data,"Your mass storage device size is ")
print_maxvar_dec(serial_data,byte*6(usb_msd_num_of_blocks)*512)
print_string(serial_data," bytes.")

--------------------------------------------------------------------------------
-- main Program
--------------------------------------------------------------------------------

-- define procedures and variables
procedure usb_disconnected_tasks()
procedure usb_connected_tasks()
var word char_count = 0
var word usb_check = 0
var byte usb_connected = TRUE

-- main loop to serve USB
forever loop
   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- Check if usb is still connected
   -- Another way would be to check the voltage on a USB+ pin.
   if USB_EVENT_OCCURRED == 1 then
      usb_check = 0
   elsif usb_check == 0xFFFF then
      -- USB is not connected
      usb_disconnected_tasks() -- perform your tasks
   else
      -- USB is connected
      usb_connected_tasks()    -- tasks while connected
      usb_check = usb_check + 1
   end if
end loop

-- Do anything you want here while usb is disconnected.
-- Quit the procedure when USB_EVENT_OCCURRED = 1
procedure usb_disconnected_tasks() is
   if usb_connected == TRUE then
      print_crlf(serial_data)
      print_string(serial_data, "USB is disconnected." )
      usb_connected = FALSE
   end if

   forever loop
      serial_data = "!"
      delay_1s(1)

      if USB_EVENT_OCCURRED == 1 then
         exit loop
      end if
   end loop
end procedure

-- Do anything you want here while usb is connected, but don't take long!
procedure usb_connected_tasks() is
   if usb_connected == FALSE then
      ;-- wait till MSD is configured
      usb_msd_wait_configured()
      print_crlf(serial_data)
      print_string(serial_data, "USB is connected." )
      usb_connected = TRUE
   end if

   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- let us know the PIC is actually doing something
   -- by sending char "." to serial port
   if char_count == 40000 then
      serial_data = "."
      _usec_delay(100)
      char_count = 0
   end if
   char_count = char_count + 1
end procedure

Generated by JALlib CHM Help System | Source: usb_msd.jal


usb_msd_wait_configured - JALlib Procedures Help

usb_msd_wait_configured JALLIB PROCEDURE

Signature

procedure usb_msd_wait_configured() is

Description

Wait till msd is configured

Include

To use this procedure, include the library:

include usb_msd

Parameters

None

Return Value

None

Example

From sample file: 18f67j50_usb_msd_pata_hard_disk.jal

-- Title: USB Mass Storage Device Sample (pata hard disk)
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: Test program for USB MSD (Mass Storage Device) with pata hard disk.
--
--              Here are my speed tests:
--              Read Speed                               - 200KB/s
--              Write Speed                              - 180KB/s
--
-- This file has been generated by hand (manually maintained)
--
-- Sources:
-- http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
-- http://www.usb.org/developers/devclass_docs/usbmass-ufi10.pdf
-- http://direction.scene-double.com/2008/07/08/usb-msd-bootloader-for-pic-microcontrollers.aspx
--
-- Notes:
--

include 18f67j50                      -- target PICmicro
--
-- This program uses the internal oscillator with PLL active.
pragma target clock 48_000_000      -- oscillator frequency
--
pragma target OSC      INTOSC_NOCLKOUT_PLL       -- internal oscillator
pragma target PLLDIV   P2                        -- 8 MHz -> 4 MHz
pragma target CPUDIV   P1                        -- Fosc divisor
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- use PLL
--
enable_digital_io()                 -- make all pins digital I/O
--
include delay                       -- library with delay procedures

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

include format

-- enable usb debugging
const bit USB_DEBUG = FALSE
const bit USB_DEBUG_HIGH = FALSE
;const bit USB_HID_DEBUG = TRUE
;const bit USB_HID_DEBUG_HIGH = TRUE

-- setup debug lib
alias debug_data is serial_data
const bit DEBUG_MASTER_ENABLE = OFF    -- enables debugging
include debug
--
-- turn on and off debug levels.
debug_lvl_0 = ON  -- short debugging
debug_lvl_1 = OFF  -- display data in/out
debug_lvl_2 = OFF  -- display commands
debug_lvl_3 = OFF  -- short debug info
--
const byte debug_text0[] = "DEBUG STARTED"
debug_string(DEBUG_0,debug_text0)
debug_crlf(DEBUG_0)
--

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = TRUE -- uses additonal code space to add a speed boost to sector_read procedures
const byte PATA_HD_USE_CS0_CS1_PINS = TRUE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_reset                 is pin_e5 -- reset pin
alias     pata_hd_reset_direction       is pin_e5_direction
alias     pata_hd_data_low              is porta   -- data port (low bits)
alias     pata_hd_data_low_direction    is porta_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_g2
alias     pata_hd_a0_direction          is pin_g2_direction
alias     pata_hd_a1                    is pin_g3
alias     pata_hd_a1_direction          is pin_g3_direction
alias     pata_hd_a2                    is pin_g4
alias     pata_hd_a2_direction          is pin_g4_direction
alias     pata_hd_iowr                  is pin_g0
alias     pata_hd_iowr_direction        is pin_g0_direction
alias     pata_hd_iord                  is pin_g1
alias     pata_hd_iord_direction        is pin_g1_direction
alias     pata_hd_cs1                   is pin_c1
alias     pata_hd_cs1_direction         is pin_c1_direction
alias     pata_hd_cs0                   is pin_c0
alias     pata_hd_cs0_direction         is pin_c0_direction
--
pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
pata_hd_cs1_direction = output   -- register select pin
pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup MSD library
include usb_msd
usb_msd_init()
print_crlf(serial_data)
print_string(serial_data,"Your mass storage device size is ")
print_maxvar_dec(serial_data,byte*6(usb_msd_num_of_blocks)*512)
print_string(serial_data," bytes.")

--------------------------------------------------------------------------------
-- main Program
--------------------------------------------------------------------------------

-- define procedures and variables
procedure usb_disconnected_tasks()
procedure usb_connected_tasks()
var word char_count = 0
var word usb_check = 0
var byte usb_connected = TRUE

-- main loop to serve USB
forever loop
   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- Check if usb is still connected
   -- Another way would be to check the voltage on a USB+ pin.
   if USB_EVENT_OCCURRED == 1 then
      usb_check = 0
   elsif usb_check == 0xFFFF then
      -- USB is not connected
      usb_disconnected_tasks() -- perform your tasks
   else
      -- USB is connected
      usb_connected_tasks()    -- tasks while connected
      usb_check = usb_check + 1
   end if
end loop

-- Do anything you want here while usb is disconnected.
-- Quit the procedure when USB_EVENT_OCCURRED = 1
procedure usb_disconnected_tasks() is
   if usb_connected == TRUE then
      print_crlf(serial_data)
      print_string(serial_data, "USB is disconnected." )
      usb_connected = FALSE
   end if

   forever loop
      serial_data = "!"
      delay_1s(1)

      if USB_EVENT_OCCURRED == 1 then
         exit loop
      end if
   end loop
end procedure

-- Do anything you want here while usb is connected, but don't take long!
procedure usb_connected_tasks() is
   if usb_connected == FALSE then
      ;-- wait till MSD is configured
      usb_msd_wait_configured()
      print_crlf(serial_data)
      print_string(serial_data, "USB is connected." )
      usb_connected = TRUE
   end if

   -- poll the usb ISR function on a regular base, in order to
   -- serve the USB MSD requests
   usb_msd_tasks()

   -- let us know the PIC is actually doing something
   -- by sending char "." to serial port
   if char_count == 40000 then
      serial_data = "."
      _usec_delay(100)
      char_count = 0
   end if
   char_count = char_count + 1
end procedure

Generated by JALlib CHM Help System | Source: usb_msd.jal


usb_prime_epx_out - JALlib Procedures Help

usb_prime_epx_out JALLIB PROCEDURE

Signature

procedure usb_prime_epx_out( byte in end_point, byte in size ) is

Description

Initialize the given OUT endpoints with the given size.

Include

To use this procedure, include the library:

include usb_drv_core

Parameters

  • end_point - byte in
  • size - byte in

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_drv_core.jal


usb_send_data - JALlib Procedures Help

usb_send_data JALLIB PROCEDURE

Signature

procedure usb_send_data(byte in endpoint, byte in data[], byte in byte_cnt, bit in is_new_sequence ) is

Description

This procedure will send the content of an array to the USB end point. The endpoint
input parameter contains the the enpoint number, data[] is the content to be send,
byte_cnt the number of bytes to be send, and is_new_sequence determines if the data
tranmission is starting with USB packet o (if set to true), otherwise the USB packet
is toggled before transmission.
Note: This function is not yet used by the USB driver.

Include

To use this procedure, include the library:

include usb_drv_core

Parameters

  • endpoint - byte in
  • data[] - byte in
  • byte_cnt - byte in
  • is_new_sequence - bit in

Return Value

None

Example

From sample file: 18f2550_usb_hid_mouse.jal

-- Title: USB HID device demo
-- Author: Albert Faber, Copyright (c) 2008..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a mouse pointing USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID is recognized by
-- the host operating systems, it will move around the mouse pointer
-- --
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: compiled with following flags
-- -loader18 -no-fuse
-- use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- ------------------------------------------------------
-- ------------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_hid_mouse.jal
--

;@jallib section board_description

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

include delay

;@jallib section serial

-- whether or not using the serial port
const HAS_SERIAL_DEBUG_PORT = 1

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

  -- uncomment when directly coupled (i.e. without max 232) to rs-232C
  -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure
end if

const bit USB_DEBUG = false
const bit USB_DEBUG_HIGH = false
const bit USB_HID_DEBUG = false
const bit USB_HID_DEBUG_HIGH = false
const byte USB_HID_ENDPOINT = 0x01
var volatile bit usb_hid_can_tx = true

include usb_defs

const bit USB_EP0 = 1
const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 8
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = 8
const word USB_EP1_IN_ADDR  = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )

var volatile byte  usb_ep1in_buf[ 8 ] at USB_EP1_IN_ADDR

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    0x08,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x00,
    0x00,		-- Mouse circle demo
    0x02,
    0x00, 	     -- version 2.0 of the product
    0x01,		-- string 1 for manufacturer
    0x02,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x09 + 0x07

const byte USB_HID_REPORT1[]=
{
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x02, -- Usage (Mouse)
    0xA1, 0x01, -- Collection (Application)
    0x09, 0x01, -- Usage (Pointer)
    0xA1, 0x00, -- Collection (Physical)
    0x05, 0x09, -- Usage Page (Buttons)
    0x19, 0x01, -- Usage Minimum (01)
    0x29, 0x03, -- Usage Maximum (03)
    0x15, 0x00, -- Logical Minimum (0)
    0x25, 0x01, -- Logical Maximum (0)
    0x95, 0x03, -- Report Count (3)
    0x75, 0x01, -- Report Size (1)
    0x81, 0x02, -- Input (Data, Variable, Absolute)
    0x95, 0x01, -- Report Count (1)
    0x75, 0x05, -- Report Size (5)
    0x81, 0x01, -- Input (Constant), 5 bit padding
    0x05, 0x01, -- Usage Page (Generic Desktop)
    0x09, 0x30, -- Usage (X)
    0x09, 0x31, -- Usage (Y)
    0x15, 0x81, -- Logical Minimum (-127)
    0x25, 0x7F, -- Logical Maximum (127)
    0x75, 0x08, -- Report Size (8)
    0x95, 0x02, -- Report Count (2)
    0x81, 0x06, -- Input (Data, Variable, Relative)
    0xC0, 0xC0
}

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,	-- length,
    USB_DT_INTERFACE,	-- descriptor_type,
    0x00,	-- interface_number, (starts at zero)
    0x00,	-- alternate_setting, (no alternatives)
    0x01,	-- num_endpoints,
    0x03,	-- interface_class, (HID)
    0x01,	-- interface_subclass, (boot - is this necessary?)
    0x02,	-- interface_protocol, (mouse)
    0x00,	-- interface_string_id;

    -- hid descriptor - - - - - - - - - - - - - - -
    0x09,				-- length,
    USB_DT_HID,			-- descriptor_type;
    0x11,
    0x01,				-- hid_spec in BCD (1.11)
    0x00,				-- country_code, (0=not country specific)
    0x01,				-- num_class_descriptors, (1)
    USB_DT_HID_REPORT,	-- class_descriptor_type; (0x22 = report)
    (count( USB_HID_REPORT1 ) & 0xFF ),
    (count( USB_HID_REPORT1 ) >> 8 ),

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    0b00000011,			-- attributes; (Interrupt)
    0x03,
    0x00,				-- max_packet_size
    0x0A				-- interval (10ms)
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

const byte USB_STRING1[] =
{
    0x36,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "M", 0x00,
    "i", 0x00,
    "c", 0x00,
    "r", 0x00,
    "o", 0x00,
    "c", 0x00,
    "h", 0x00,
    "i", 0x00,
    "p", 0x00,
    " ", 0x00,
    "T", 0x00,
    "e", 0x00,
    "c", 0x00,
    "h", 0x00,
    "n", 0x00,
    "o", 0x00,
    "l", 0x00,
    "o", 0x00,
    "g", 0x00,
    "y", 0x00,
    ",", 0x00,
    " ", 0x00,
    "I", 0x00,
    "n", 0x00,
    "c", 0x00,
    ".", 0x00
}

const byte USB_STRING2[44] =
{
    44,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    "J", 0x00,
    "A", 0x00,
    "L", 0x00,
    "L", 0x00,
    "I", 0x00,
    "B", 0x00,
    " ", 0x00,
    "H", 0x00,
    "I", 0x00,
    "D", 0x00,
    " ", 0x00,
    "M", 0x00,
    "o", 0x00,
    "u", 0x00,
    "s", 0x00,
    "e", 0x00,
    " ", 0x00,
    "D", 0x00,
    "e", 0x00,
    "m", 0x00,
    "o", 0x00
}

include usb_drv_core

procedure usb_ep_data_in_callback(byte in end_point, word in buffer_addr, byte  in byte_count) is
    pragma inline
    if USB_HID_DEBUG_HIGH then
        const byte str[] = " EP data in: "
        const byte str1[] = " bytes "
        print_string( serial_hw_data,str )
        print_byte_hex( serial_hw_data, byte_count & 0xFF)
        print_string(serial_hw_data,str1)
    end if

    -- data has been sent, so do we need to send more?
    if (end_point == USB_HID_ENDPOINT) then
        -- it's the data end point
        usb_hid_can_tx = true
    end if
end procedure

include usb_drv

-- constants
const sbyte dir_table[] = {-4,-4,-4, 0, 4, 4, 4, 0}
const  byte str_welcome[] = "JALLIB USB HID MOUSE DEMO version 1.0\nplease wait (takes ~10 seconds) before the device it is fully configured"

-- variables
var word i = 0
var byte movement_length
var byte vector = 0
var bit usb_initialized = false
var byte data_buffer[3]
var word ticks100us = 0
var bit enable_mouse = false

procedure usb_tasks() is
    -- Servicing Hardware
    -- use polling method
    usb_handle_isr()
end procedure

-- interrupts? No thanks
while INTCON_GIE loop
    INTCON_GIE = false
end loop

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

-- setup the USB device
usb_setup()

-- enable USB device
usb_enable_module()

-- initialize HID buffer
data_buffer[0] = 0x00
data_buffer[1] = 0x00
data_buffer[2] = 0x00

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_tasks()

    -- check if USB device has been configured by the HOST
    if usb_is_configured()  then

        -- note user via serial line that USB has been configured
        if usb_initialized == false then
            usb_initialized = true

            if defined( HAS_SERIAL_DEBUG_PORT ) == true then
                const  byte str[] = "USB device has been configured by the HOST!"
                print_string(serial_hw_data, str )
                serial_newline()
            end if
        end if

        -- now the mouse pointer can be moved around
        enable_mouse = true
    end if

    if enable_mouse then
        ticks100us = ticks100us + 1
        delay_10us(10)

        if ticks100us == 250 then
            ticks100us = 0

            if( movement_length > 16 ) then
                data_buffer[0] = 0
                data_buffer[1] = byte( dir_table[vector & 0x07] ) -- X-Vector
                data_buffer[2] = byte( dir_table[(vector+2) & 0x07] ) -- Y-Vector
                vector = vector+1
                movement_length = 0
            end if

            if 	( usb_hid_can_tx ) then
                usb_hid_can_tx = false
                usb_send_data(1, data_buffer, 3, low )
                movement_length =  movement_length + 1
            end if

        end if
    end if

    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
            serial_hw_write( RCREG )

            if RCREG == "S" then
            end if
            if RCREG == "T" then
            end if
        end if
    end if

end loop

Generated by JALlib CHM Help System | Source: usb_drv_core.jal


usb_serial.jal - JALLIB Library Documentation

usb_serial.jal JALLIB LIBRARY

Title

USB Serial

Author

Albert Faber, Copyright (c) 2009..2021, all rights reserved., Adapted-by: Rob Jansen

Compiler

2.5r5

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

The library will ease the use of for serial communication over
the USB interface. By default nothing has to be defined by the user, below
an example how to use the library
--
include usb_serial
..
usb_serial_init()
..
;-- optionally wait till USB becomes available
while ( usb_cdc_line_status() == 0x00 ) loop
end loop
..
;-- main loop
var byte ch
forever loop
; -- Call the flush routine on a regular base in the main loop
; -- in order to keep the USB communicaiton alive.
; -- This is only needed when USB_INTERRUPT_DRIVEN is not defined, otherwise
; -- the usb_serial_flush() is not needed, see notes.
;
usb_serial_flush()
if ( usb_serial_read( ch ) )
usb_serial_data = ch -- echo
end if
.....
end loop
--
In addition this library can be used in combination with other JAL
libraries, like print.jal and format.jal, for example to send a
string, one can use the following code fragment:
--
const byte str[] = "Hello World"
print_string( usb_serial_data, str )
--
customization
The usb_serial library offers the following custimization prameters,
the user has the ability to set these const parameter(s) before the
inclusion of the usb_serial file
--
const byte USB_CDC_RX_BUFFER_SIZE = 0x?? -- set receive FIFO size
const byte USB_CDC_TX_BUFFER_SIZE = 0x?? -- set transmit FIFO size
const word USB_SERIAL_PRODUCT_ID = 0x???? -- set USB device product ID
const word USB_SERIAL_VENDOR_ID = 0x???? -- set USB device vendor ID
const byte USB_STRING0[] = { .. } -- set USB language string
const byte USB_STRING1[] = { .. } -- set USB mfg string
const byte USB_STRING2[] = { .. } -- set USB product string

Notes

There are two options to use the USB driver for serial:
1) Without interrupts by frequently calling 'usb_serial_flush()'
frequently in the main loop.
2) Using interrupts. In that case no calls to 'usb_serial_flush()' are
needed. This can be activated by defining
const USB_INTERRUPT_DRIVEN = TRUE

-----------------------------------------------------------------------
consts to enable debugging
Note that not all can be enabled at the same time since the USB
device might not be recognized by the Host.
-----------------------------------------------------------------------

Constants and Variables

USB_EP0 - const bit = 1
USB_EP0_OUT_SIZE - const byte = 8
USB_EP0_OUT_ADDR - const word = ( USB_EP0_ADDRESS )
USB_EP0_IN_SIZE - const byte = 8
USB_EP0_IN_ADDR - const word = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )
USB_EP1 - const bit = 1
USB_EP1_OUT_SIZE - const byte = 8
USB_EP1_OUT_ADDR - const word = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
USB_EP1_IN_SIZE - const byte = 8
USB_EP1_IN_ADDR - const word = ( USB_EP1_OUT_ADDR + USB_EP1_OUT_SIZE )
USB_EP2 - const bit = 1
USB_EP2_OUT_SIZE - const byte = 8
USB_EP2_OUT_ADDR - const word = ( USB_EP1_IN_ADDR + USB_EP1_IN_SIZE )
USB_EP2_IN_SIZE - const byte = 8
USB_EP2_IN_ADDR - const word = ( USB_EP2_OUT_ADDR + USB_EP2_OUT_SIZE )
USB_EP3 - const bit = 1
USB_EP3_OUT_SIZE - const byte = 8
USB_EP3_OUT_ADDR - const word = ( USB_EP2_IN_ADDR + USB_EP2_IN_SIZE )
USB_EP3_IN_SIZE - const byte = 8 -- Size may be changed, see comment below.
Size may be changed, see comment below.
USB_EP3_IN_ADDR - const word = ( USB_EP3_OUT_ADDR + USB_EP3_OUT_SIZE )
USB_CDC_TX_BUFFER_SIZE - const byte = 0x20
USB_CDC_RX_BUFFER_SIZE - const byte = 0x10
USB_CDC_DATA_ENDPOINT - const byte = 3
USB_CS_INTERFACE - const byte = 0x24
USB_CS_ENDPOINT - const byte = 0x25
USB_DCS_INTERFACE - const byte = 0x04
USB_CDC_DATA_INTF - const byte = 0x0A
USB_CDC_NO_PROTOCOL - const byte = 0x00 -- No class specific protocol required
No class specific protocol required
USB_DSC_FN_HEADER - const byte = 0x00
USB_DSC_FN_CALL_MGT - const byte = 0x01
USB_DSC_FN_ACM - const byte = 0x02 -- ACM - Abstract Control Management
ACM - Abstract Control Management
USB_DSC_FN_DLM - const byte = 0x03 -- DLM - Direct Line Managment
DLM - Direct Line Managment
USB_DSC_FN_TELEPHONE_RINGER - const byte = 0x04
USB_DSC_FN_RPT_CAPABILITIES - const byte = 0x05
USB_DSC_FN_UNION - const byte = 0x06
USB_DSC_FN_COUNTRY_SELECTION - const byte = 0x07
USB_DSC_FN_TEL_OP_MODES - const byte = 0x08
USB_DSC_FN_USB_TERMINAL - const byte = 0x09
USB_CDC_COMM_INTF_ID - const byte = 0x00
USB_CDC_INT_EP_SIZE - const byte = 8
USB_CDC_DATA_INTF_ID - const byte = 0x01
USB_CDC_BULK_OUT_EP_SIZE - const byte = USB_EP3_OUT_SIZE
USB_CDC_BULK_IN_EP_SIZE - const byte = USB_EP3_IN_SIZE
USB_CDC_BULK_OUT_EP_ADDR - const word = USB_EP3_OUT_ADDR
USB_CDC_BULK_IN_EP_ADDR - const word = USB_EP3_IN_ADDR
USB_SERIAL_VENDOR_ID - const word = 0x04D8
USB_SERIAL_PRODUCT_ID - const word = 0x000A

Routines

  • _usb_serial_read - Function returns bit
  • usb_serial_data'get - Function returns byte
  • usb_serial_data'put - Procedure
  • usb_serial_data_available'get - Function returns bit
  • usb_serial_flush - Procedure
  • usb_serial_init - Procedure
  • usb_serial_port_open'get - Function returns bit
  • usb_serial_read - Function returns bit
  • usb_serial_write - Procedure


usb_serial_flush - JALlib Procedures Help

usb_serial_flush JALLIB PROCEDURE

Signature

procedure usb_serial_flush() is

Description

usb_serial_flush shall be called on a regular base (millisecond range)
in order to keep the USB transmision alive. Therefore it is adviced to
call the usb_serial_flush procedure in the main loop of your
application.
Note: Only needed when USB interrupt is not used otherwise this call
can be omitted (it does nothing in interrupt mode).

Include

To use this procedure, include the library:

include usb_serial

Parameters

None

Return Value

None

Example

From sample file: 16f1455_tutorial_usb_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Tutorial USB Serial Demo
-- Author: Rob Jansen, Copyright (c) 2022..2024, all rights reserved.
-- Adapted-by: Rob Hamerling, Rob Jansen
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This application demonstrates the functionality of the USB Serial library,
--              this application will emulate a RS-232 terminal device. Once the USB device
--              has been detected by the host operating system, it will create a virtual
--              serial (COM) port. When opening this port on the host computer using a
--              standard terminal application 2 LEDs can remotely be controlled.
--              The status of the LEDs is returned to the host.-
--
--
-- Notes: For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
--        the USB connection and the PIC16F1455 is connected as follows:
--        *) USB data- wire to pin 12 (A1 / D-)
--        *) USB data+ wire to pin 13 (A0 / D+)
--        *) USB power wire to pin 1 (VDD). Don't forget a 100nF decoupling capacitor.
--        *) USB ground wire to pin 14 (VSS or GND)
--        *) A resistor of 33kOhm to pin 4 (MCLR) and VDD. We use internal reset.
--        *) A capacitor of 470nF to pin 11 (Vusb3v3) and GND.
--        *) A Yellow LED with 330 Ohm resistor to pin 8 (C2).
--           (indicates that USB is configured.)
--        *) A Red LED with 330 Ohm resistor to pin 6 (C4).
--        *) A Green LED with 330 Ohm resistor to pin 7 (C3).
--
--        For In Circuit Serial Programming:
--        *) ICSPDAT wire to pin 10 (C0)
--        *) ICSPCLK wire to pin 9 (C1)
--
include 16f1455             -- Target processor.

pragma target clock         48_000_000

-- Settings for internal clock and system clock 48 MHz.
pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses.
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- External reset
pragma target LVP           ENABLED  -- allow low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a and and set port c to output just to
-- have no floating input pins.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1111          -- Weak-pull up for all inputs.
TRISC         = 0b0000_0000          -- Port c output.

-- Include serial library and print library for formatting print output.
include usb_serial
include print

-- Aliases for LEDs, active HIGH.
alias led_red is pin_C4
pin_C4_direction = output            -- Pin 6 of 14 pin DIP.
alias led_green is pin_C3
pin_C3_direction = output            -- Pin 7 of 14 pin DIP.
alias led_yellow is pin_C2
pin_C2_direction = output            -- Pin 8 of 14 pin DIP.

-- Variables.
var byte character
var bit red_value, green_value

-- ------------- The main program starts here  ------------------------

-- Setup the USB serial library.
usb_serial_init()

-- LEDs off.
led_yellow = FALSE
red_value = FALSE
green_value = FALSE

forever loop

   -- Update Red and Green LEDs.
   led_red = red_value
   led_green = green_value

   -- Poll the usb ISR function on a regular base,
   -- in order to serve the USB requests
   usb_serial_flush()

   -- Check if USB device has been configured by the host.
   if ( usb_cdc_line_status() !=  0x00 )  then
      led_yellow = TRUE
   else
      led_yellow = FALSE    -- disconnected
      red_value = FALSE     -- red led off
      green_value = FALSE   -- green led off
   end if

   -- Check for input character. If OK, toggle led value and report to host.
   if usb_serial_read(character) then
      if (character == "R") | (character == "r") then
         red_value = !red_value
         print_string(usb_serial_data, "Red LED is ")
         if red_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      elsif (character == "G") | (character == "g") then
         green_value = !green_value
         print_string(usb_serial_data, "Green LED is ")
         if green_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      else
         print_string(usb_serial_data, "Expecting 'r' or 'g'")
      end if
      print_crlf(usb_serial_data)
   end if

end loop
--

Generated by JALlib CHM Help System | Source: usb_serial.jal


usb_serial_init - JALlib Procedures Help

usb_serial_init JALLIB PROCEDURE

Signature

procedure usb_serial_init() is

Description

usb_serial_init will setup the USB communication, however, this can be
a time consuming process, therefore this call is non blocking.
In order to check if the USB device has established contact with the
HOST USB device, one can call the usb_is_configured() function, see
usb_is_configured() documentation for additional details.

Include

To use this procedure, include the library:

include usb_serial

Parameters

None

Return Value

None

Example

From sample file: 16f1455_tutorial_usb_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Tutorial USB Serial Demo
-- Author: Rob Jansen, Copyright (c) 2022..2024, all rights reserved.
-- Adapted-by: Rob Hamerling, Rob Jansen
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This application demonstrates the functionality of the USB Serial library,
--              this application will emulate a RS-232 terminal device. Once the USB device
--              has been detected by the host operating system, it will create a virtual
--              serial (COM) port. When opening this port on the host computer using a
--              standard terminal application 2 LEDs can remotely be controlled.
--              The status of the LEDs is returned to the host.-
--
--
-- Notes: For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
--        the USB connection and the PIC16F1455 is connected as follows:
--        *) USB data- wire to pin 12 (A1 / D-)
--        *) USB data+ wire to pin 13 (A0 / D+)
--        *) USB power wire to pin 1 (VDD). Don't forget a 100nF decoupling capacitor.
--        *) USB ground wire to pin 14 (VSS or GND)
--        *) A resistor of 33kOhm to pin 4 (MCLR) and VDD. We use internal reset.
--        *) A capacitor of 470nF to pin 11 (Vusb3v3) and GND.
--        *) A Yellow LED with 330 Ohm resistor to pin 8 (C2).
--           (indicates that USB is configured.)
--        *) A Red LED with 330 Ohm resistor to pin 6 (C4).
--        *) A Green LED with 330 Ohm resistor to pin 7 (C3).
--
--        For In Circuit Serial Programming:
--        *) ICSPDAT wire to pin 10 (C0)
--        *) ICSPCLK wire to pin 9 (C1)
--
include 16f1455             -- Target processor.

pragma target clock         48_000_000

-- Settings for internal clock and system clock 48 MHz.
pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses.
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- External reset
pragma target LVP           ENABLED  -- allow low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a and and set port c to output just to
-- have no floating input pins.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1111          -- Weak-pull up for all inputs.
TRISC         = 0b0000_0000          -- Port c output.

-- Include serial library and print library for formatting print output.
include usb_serial
include print

-- Aliases for LEDs, active HIGH.
alias led_red is pin_C4
pin_C4_direction = output            -- Pin 6 of 14 pin DIP.
alias led_green is pin_C3
pin_C3_direction = output            -- Pin 7 of 14 pin DIP.
alias led_yellow is pin_C2
pin_C2_direction = output            -- Pin 8 of 14 pin DIP.

-- Variables.
var byte character
var bit red_value, green_value

-- ------------- The main program starts here  ------------------------

-- Setup the USB serial library.
usb_serial_init()

-- LEDs off.
led_yellow = FALSE
red_value = FALSE
green_value = FALSE

forever loop

   -- Update Red and Green LEDs.
   led_red = red_value
   led_green = green_value

   -- Poll the usb ISR function on a regular base,
   -- in order to serve the USB requests
   usb_serial_flush()

   -- Check if USB device has been configured by the host.
   if ( usb_cdc_line_status() !=  0x00 )  then
      led_yellow = TRUE
   else
      led_yellow = FALSE    -- disconnected
      red_value = FALSE     -- red led off
      green_value = FALSE   -- green led off
   end if

   -- Check for input character. If OK, toggle led value and report to host.
   if usb_serial_read(character) then
      if (character == "R") | (character == "r") then
         red_value = !red_value
         print_string(usb_serial_data, "Red LED is ")
         if red_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      elsif (character == "G") | (character == "g") then
         green_value = !green_value
         print_string(usb_serial_data, "Green LED is ")
         if green_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      else
         print_string(usb_serial_data, "Expecting 'r' or 'g'")
      end if
      print_crlf(usb_serial_data)
   end if

end loop
--

Generated by JALlib CHM Help System | Source: usb_serial.jal


usb_serial_read - JALlib Procedures Help

usb_serial_read JALLIB FUNCTION

Signature

function usb_serial_read(byte out data) return bit is

Description

usb_serial_read - read char if available (non-blocking)
usb_serial_read returns true if a character has been received,
otherwise returns false. If function returns true, the data variable
is valid, and contains the character that has been received. In other
cases the data variable is not defined
Note that characters are dropped when the communcation channel on the
USB host side is not opened (yet), this is a design choice in order to
avoid lockup(s)

Include

To use this procedure, include the library:

include usb_serial

Parameters

  • data - byte out

Return Value

bit - Function return value

Example

From sample file: 16f1455_tutorial_usb_serial.jal

-- -----------------------------------------------------------------------------
-- Title: Tutorial USB Serial Demo
-- Author: Rob Jansen, Copyright (c) 2022..2024, all rights reserved.
-- Adapted-by: Rob Hamerling, Rob Jansen
-- Compiler: 2.5r8
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: This application demonstrates the functionality of the USB Serial library,
--              this application will emulate a RS-232 terminal device. Once the USB device
--              has been detected by the host operating system, it will create a virtual
--              serial (COM) port. When opening this port on the host computer using a
--              standard terminal application 2 LEDs can remotely be controlled.
--              The status of the LEDs is returned to the host.-
--
--
-- Notes: For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
--        the USB connection and the PIC16F1455 is connected as follows:
--        *) USB data- wire to pin 12 (A1 / D-)
--        *) USB data+ wire to pin 13 (A0 / D+)
--        *) USB power wire to pin 1 (VDD). Don't forget a 100nF decoupling capacitor.
--        *) USB ground wire to pin 14 (VSS or GND)
--        *) A resistor of 33kOhm to pin 4 (MCLR) and VDD. We use internal reset.
--        *) A capacitor of 470nF to pin 11 (Vusb3v3) and GND.
--        *) A Yellow LED with 330 Ohm resistor to pin 8 (C2).
--           (indicates that USB is configured.)
--        *) A Red LED with 330 Ohm resistor to pin 6 (C4).
--        *) A Green LED with 330 Ohm resistor to pin 7 (C3).
--
--        For In Circuit Serial Programming:
--        *) ICSPDAT wire to pin 10 (C0)
--        *) ICSPCLK wire to pin 9 (C1)
--
include 16f1455             -- Target processor.

pragma target clock         48_000_000

-- Settings for internal clock and system clock 48 MHz.
pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses.
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- External reset
pragma target LVP           ENABLED  -- allow low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a and and set port c to output just to
-- have no floating input pins.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1111          -- Weak-pull up for all inputs.
TRISC         = 0b0000_0000          -- Port c output.

-- Include serial library and print library for formatting print output.
include usb_serial
include print

-- Aliases for LEDs, active HIGH.
alias led_red is pin_C4
pin_C4_direction = output            -- Pin 6 of 14 pin DIP.
alias led_green is pin_C3
pin_C3_direction = output            -- Pin 7 of 14 pin DIP.
alias led_yellow is pin_C2
pin_C2_direction = output            -- Pin 8 of 14 pin DIP.

-- Variables.
var byte character
var bit red_value, green_value

-- ------------- The main program starts here  ------------------------

-- Setup the USB serial library.
usb_serial_init()

-- LEDs off.
led_yellow = FALSE
red_value = FALSE
green_value = FALSE

forever loop

   -- Update Red and Green LEDs.
   led_red = red_value
   led_green = green_value

   -- Poll the usb ISR function on a regular base,
   -- in order to serve the USB requests
   usb_serial_flush()

   -- Check if USB device has been configured by the host.
   if ( usb_cdc_line_status() !=  0x00 )  then
      led_yellow = TRUE
   else
      led_yellow = FALSE    -- disconnected
      red_value = FALSE     -- red led off
      green_value = FALSE   -- green led off
   end if

   -- Check for input character. If OK, toggle led value and report to host.
   if usb_serial_read(character) then
      if (character == "R") | (character == "r") then
         red_value = !red_value
         print_string(usb_serial_data, "Red LED is ")
         if red_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      elsif (character == "G") | (character == "g") then
         green_value = !green_value
         print_string(usb_serial_data, "Green LED is ")
         if green_value then
            print_string(usb_serial_data, "on")
         else
            print_string(usb_serial_data, "off")
         end if
      else
         print_string(usb_serial_data, "Expecting 'r' or 'g'")
      end if
      print_crlf(usb_serial_data)
   end if

end loop
--

Generated by JALlib CHM Help System | Source: usb_serial.jal


usb_setup - JALlib Procedures Help

usb_setup JALLIB PROCEDURE

Signature

procedure usb_setup() is

Description

Procedure to intialize the USB device, it will only do the setup, to enable
the USB device, use the usb_enable() procedure

Include

To use this procedure, include the library:

include usb_drv

Parameters

None

Return Value

None

Example

From sample file: 18f2550_usb_bootloader_autostart.jal

-- Title: USB (legacy) bootloader
-- Author: Albert Faber, Copyright (c) 2009..2014, all rights reserved.
-- Adapted-by: Joep Suijs
-- Compiler: >=2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application implements the Microchip PDF/USB bootloader (legacy)
-- The compiled code shall fit in the first 1024 words 0x0000..0x0800
-- The booloader checks the bootloader_program_pin, if it is low at initialization time
-- the bootloader will be activated, otherwise the user program (starting at 0x800) is
-- executed. Currently only the high priority interrupts are supported, since JAL does
-- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility
-- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data
--
-- Sources: http://www.microchip.org for PICDEM specifications
--
-- Notes: compiled with following flags
--	use -no-variable-reuse when debugging flags are
--  set due to a compiler issue
--
-- -----------------------------------------------------
--
-- This file has been generated by jallib.py from:
--    * board: board_18f2550_js.jal
--    * test : test_usb_bootloader_autostart.jal
--

-- whether or not using the serial port
-- const HAS_SERIAL_DEBUG_PORT = 1
-- const STUB_ERASE = 1
-- const STUB_WRITE_FLASH = 1

-- needed to get compact code, bootloader has to
-- fit within first 2048 bytes in order to be
-- compatible with default of PDFSUSB
-- currently only 14 bytes left (2010 bytes) for a 18f4550
-- and only 18 bytes left (2006 bytes) for a 18f14k50

PRAGMA OPT CONST_DETECT YES

;@jallib section chipdef
-- chip setup
include 18f2550

pragma target  clock 20_000_000
pragma target  OSC        hs
pragma target  LVP enabled                   -- allow LVP
pragma target  WDT CONTROL                   -- WDT software controlled

WDTCON_SWDTEN = OFF                          -- disable WDT

;@jallib use bootloader

-- boot timer delay (practical values between 1..10 seconds)
const BOOT_DELAY_IN_SECONDS = 10

-- timer ticks: clock / 4 / prescaler = 8  / 16 timer overflow
const TIMER_TICKS_PER_SECOND = target_clock / 65536 / 8 / 4
const BOOT_TIMER_TICS = BOOT_DELAY_IN_SECONDS * TIMER_TICKS_PER_SECOND

if ( BOOT_TIMER_TICS > 256) then
   pragma error "Boot delay too large"
end if

const byte READ_VERSION    = 0x00
const byte READ_FLASH      = 0x01
const byte WRITE_FLASH     = 0x02
const byte ERASE_FLASH     = 0x03
const byte READ_EEDATA     = 0x04
const byte WRITE_EEDATA    = 0x05
const byte READ_CONFIG     = 0x06
const byte WRITE_CONFIG    = 0x07
const byte UPDATE_LED      = 0x32
const byte RESET           = 0xFF

const byte MINOR_VERSION   = 0x14    -- Bootloader Version 1.20
const byte MAJOR_VERSION   = 0x01

if defined( HAS_SERIAL_DEBUG_PORT ) == true then

    const serial_hw_baudrate = 115_200

    include serial_hardware
    include format
    include print

    -- intialze serial device
    serial_hw_init()

    -- uncomment when directly coupled (i.e. without max 232) to rs-232C
    -- BAUDCON_CKTXP = true

    procedure serial_print_spc() is
        serial_hw_write( " " )
    end procedure

    procedure serial_newline() is
        serial_hw_write( 10 )
        -- serial_hw_write( 13 )
    end procedure

    procedure print_nibble( byte in nibble ) is

        if nibble > 9 then
            nibble = nibble + ( "A" - 10 )
        else
            nibble = nibble + ( "0" )
        end if
        serial_hw_data = nibble
    end procedure

    procedure print_hex( byte in bt ) is
        var byte nibble = bt >> 4
        print_nibble( nibble )
        nibble = bt & 0x0F
        print_nibble( nibble )
    end procedure

    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = true
    const bit ADD_RW_OFFSET = true
else
    const bit USB_DEBUG = false
    const bit USB_HID_DEBUG = false

end if

const bit USB_DEBUG_HIGH = USB_DEBUG
const bit USB_HID_DEBUG_HIGH = USB_DEBUG

include usb_defs

const byte USB_EP0_OUT_SIZE = 8
const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 )
const byte USB_EP0_IN_SIZE  = 8
const word USB_EP0_IN_ADDR  = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE )

const bit USB_EP1 = 1
const byte USB_EP1_OUT_SIZE = 64
const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE )
const byte USB_EP1_IN_SIZE  = USB_EP1_OUT_SIZE
const word USB_EP1_IN_ADDR  = USB_EP1_OUT_ADDR -- point to the same buffer!

var volatile byte  usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR
var volatile byte  usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR
var volatile byte  boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR

-- *********************************************************************
-- * General Data Packet Structure:
-- * .
-- * __________________           boot_cmd fields
-- * |    COMMAND     |   0       [CMD]
-- * |      LEN       |   1       [LEN]
-- * |     ADDRL      |   2       [        ]  [addrl]
-- * |     ADDRH      |   3       [ADR.pAdr]: [addrh]
-- * |     ADDRU      |   4       [        ]  [addru]
-- * |                |   5       [DATA]
-- * |                |
-- * .      DATA      .
-- * .                .
-- * |                |   62
-- * |________________|   63
-- *
-- ********************************************************************/
var volatile byte  boot_cmd_cmd at boot_cmd_buffer[0]
var volatile byte  boot_cmd_len at boot_cmd_buffer[1]
var volatile byte  boot_cmd_addrl at boot_cmd_buffer[2]
var volatile byte  boot_cmd_addrh at boot_cmd_buffer[3]
var volatile byte  boot_cmd_addru at boot_cmd_buffer[4]
var volatile byte  boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5]

const bit USB_EP2 = 0
const byte USB_EP2_OUT_SIZE = 8
const word USB_EP2_OUT_ADDR = 0x0000
const byte USB_EP2_IN_SIZE  = 8
const word USB_EP2_IN_ADDR  = 0x0000

const bit USB_EP3 = 0
const byte USB_EP3_OUT_SIZE = 8
const word USB_EP3_OUT_ADDR = 0x0000
const byte USB_EP3_IN_SIZE = 8
const word USB_EP3_IN_ADDR  = 0x0000

const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = {
    USB_DEVICE_DESCRIPTOR_SIZE, 	-- 18 bytes long
    USB_DT_DEVICE, 	-- DEVICE 01h
    0x00,
    0x02,		-- usb version 2.00
    0x00,		-- class
    0x00,		-- subclass
    0x00,		-- protocol
    USB_EP0_OUT_SIZE,		-- max packet size for end point 0
    0xd8,
    0x04,		-- Microchip's vendor
    0x0b,
    0x00,		-- Microchip bootloader
    0x01,
    0x00, 	     -- version 1.0 of the product
    0x00,		-- string 1 for manufacturer
    0x00,		-- string 2 for product
    0x00,		-- string 3 for serial number
    0x01		-- number of configurations
}

const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07

const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]=
{
    -- configuration descriptor - - - - - - - - - -
    0x09,	-- length,
    USB_DT_CONFIGURATION,	-- descriptor_type

    USB_CONFIGURATION_DESCRIPTOR_SIZE,
    0x00,	-- total_length;

    0x01,	-- num_interfaces,
    0x01,	-- configuration_value,
    0x00,	-- configuration_string_id,
    0b10000000, -- attributes (bus powered, no remote wake up)
    100,	-- max_power; (200ma)

    -- interface descriptor - - - - - - - - - - - -
    0x09,						-- length,
    USB_DT_INTERFACE,			-- descriptor_type,
    0x00,						-- interface_number, (starts at zero)
    0x00,						-- alternate_setting, (no alternatives)
    0x02,						-- num_endpoints,
    0x00,						-- interface_class,
    0x00,						-- interface_subclass,
    0x00,						-- interface_protocol,
    0x00,						-- interface_string_id;

    -- endpoint descriptor(s)  - - - - - - - - - - - -
    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b10000001,			-- endpoint_address, (Endpoint 1, IN)
    USB_EPT_BULK,		-- attributes
    USB_EP1_IN_SIZE,
    0x00,				-- max_packet_size
    0x00,				-- interval

    0x07,				-- length,
    USB_DT_ENDPOINT,	-- descriptor_type,
    0b00000001,			-- endpoint_address, (Endpoint 1, OUT)
    USB_EPT_BULK,		-- attributes
    USB_EP1_OUT_SIZE,
    0x00,				-- max_packet_size
    0x00				-- interval
}

const byte USB_STRING0[] =
{
    0x04,	-- bLength
    USB_DT_STRING,	-- bDescriptorType
    0x09,	-- wLANGID[0] (low byte)
    0x04	-- wLANGID[0] (high byte)
}

include usb_drv_core

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if
end procedure

procedure start_write() is
    EECON2 = 0x55
    EECON2 = 0xAA
    EECON1_WR = 1
    if USB_HID_DEBUG then
        serial_hw_data = "S"
        serial_hw_data = "W"
        serial_hw_data = " "
        serial_hw_data = " "
        print_hex( TBLPTRU )
        print_hex( TBLPTRH )
        print_hex( TBLPTRL )
        serial_hw_data = 10
        serial_hw_data = 13
    end if
end procedure

procedure set_boot_address() is
    -- pragma inline
    TBLPTRU = boot_cmd_addru
    TBLPTRH = boot_cmd_addrh
    TBLPTRL = boot_cmd_addrl

    if defined( ADD_RW_OFFSET ) == true then
        TBLPTRH = TBLPTRH + 0x10
    end if

end procedure

procedure disable_boot() is
    var word big_counter = 0xFFFF

    -- disable timer 1
    T1CON = 0x00

    -- disable USB
    UCON = 0x00

    -- force timeout on USB
    while big_counter != 0  loop
        big_counter = big_counter - 1
    end loop
end procedure

procedure usb_ep_data_out_callback(byte in end_point, word in buffer_addr, byte in byte_count) is
    pragma inline
    var byte cdc_rx_next

    -- if USB_HID_DEBUG then
    if false then
        var byte idx
        const byte str[] = " EP data out: "
        const byte str1[] = " bytes "
        print_string(serial_hw_data,str)
        print_hex( byte_count )
        print_string(serial_hw_data,str1)
        for byte_count using idx loop
            print_hex( boot_cmd_buffer[ idx ] )
        end loop
    end if

    if USB_HID_DEBUG then
        serial_hw_data = "C"
        serial_hw_data = "M"
        serial_hw_data = "D"
        serial_hw_data = " "

        print_hex( boot_cmd_cmd )
        serial_hw_data = " "
        print_hex( boot_cmd_len )
        serial_hw_data = " "
        print_hex( boot_cmd_addru )
        print_hex( boot_cmd_addrh )
        print_hex( boot_cmd_addrl )
        serial_hw_data = " "
    end if

    usb_bd1in_cnt = 0x00

    case boot_cmd_cmd of
        READ_VERSION:
        block
            boot_cmd_buffer[2] = MINOR_VERSION;
            boot_cmd_buffer[3] = MAJOR_VERSION;
            usb_bd1in_cnt = 4
            T1CON = 0b0000_0000 -- disable timer 1
        end block

         READ_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then
                var byte counter
                EECON1_EEPGD = 0
                EECON1_CFGS = 0

                if USB_HID_DEBUG then
                    serial_hw_data = "R"
                    serial_hw_data = "E"
                    serial_hw_data = ":"
                    serial_hw_data = " "
                    print_hex( TBLPTRU )
                    print_hex( TBLPTRH )
                    print_hex( TBLPTRL )
                    serial_hw_data = 10
                    serial_hw_data = 13
                end if

                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EECON1_RD = 1;
                    boot_cmd_data[ counter ] = EEDATA
                end loop
            end if
end if

            usb_bd1in_cnt = 5 + boot_cmd_len

        end block

        READ_FLASH,READ_CONFIG:
        block
            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "R"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_READ ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    asm TBLRD*+
                    boot_cmd_data[ counter ] = TABLAT
                end loop
            end if

            usb_bd1in_cnt = 5 + boot_cmd_len
        end block
        WRITE_FLASH:
        block
             -- * The write holding register for the 18F4550 family is
             -- * actually 32-byte. The code below only tries to write
             -- * 16-byte because the GUI program only sends out 16-byte
             -- * at a time.
             -- * This limitation will be fixed in the future version.
            EECON1 = 0b_1000_0100 -- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            TBLPTRL = ( TBLPTRL & 0xF0 )   -- Force 16-byte boundary

            if USB_HID_DEBUG then
                serial_hw_data = "W"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_WRITE_FLASH ) == false then
                var volatile byte counter
                for boot_cmd_len using counter loop
                    TABLAT = boot_cmd_data[ counter ]

                    if USB_HID_DEBUG then
                        serial_hw_data = " "
                        print_hex(TABLAT)
                    end if

                    asm TBLWT*+

                    if ((counter & 0x0F ) == 0x0F ) then
                        asm TBLRD*-
                        start_write()
                    end if
                end loop
            end if

            usb_bd1in_cnt = 1

        end block
        ERASE_FLASH:
        block
            -- The most significant 16 bits of the address pointer points to the block
            -- being erased. Bits5:0 are ignored. (In hardware).

            -- LEN = # of 64-byte block to erase
            -- Setup writes: EEPGD=1,FREE=1,WREN=1
            EECON1 = 0b10010100

            set_boot_address()

            if USB_HID_DEBUG then
                serial_hw_data = "E"
                serial_hw_data = "F"
                serial_hw_data = ":"
                serial_hw_data = " "
                print_hex( TBLPTRU )
                print_hex( TBLPTRH )
                print_hex( TBLPTRL )
                serial_hw_data = 10
                serial_hw_data = 13
            end if

            if defined( STUB_ERASE ) == false then
                var byte counter
                for boot_cmd_len using counter loop
                    start_write();
                    TBLPTRL = TBLPTRL + 32
                    if TBLPTRL == 0 then
                        TBLPTRH = TBLPTRH + 1
                    end if
                end loop
                -- TBLPTRU = 0
            end if

            usb_bd1in_cnt = 1
        end block

        WRITE_EEDATA:
        block
if true then

            if defined( EECON1_EEPGD ) == true then

                var byte counter
                for boot_cmd_len using counter loop
                    EEADR = boot_cmd_addrl + counter
                    -- EEADRH = byte( (word(boot_cmd_addrl) + word(counter) ) >> 8)
                    EEDATA = boot_cmd_data[ counter ]
                    start_write()
                    while ( EECON1_WR ) loop
                    end loop
                end loop
            end if
end if
            usb_bd1in_cnt = 1
        end block

        WRITE_CONFIG:
        block

            -- * The write holding register for the 18F4550 family is
            -- * actually 32-byte. The code below only tries to write
            -- * 16-byte because the GUI program only sends out 16-byte
            -- * at a time.
            -- * This limitation will be fixed in the future version.
            EECON1 = 0b10000100								-- Setup writes: EEPGD=1,WREN=1

            set_boot_address()

            var byte counter
            for boot_cmd_len using counter loop
                TABLAT = boot_cmd_data[ counter ]

                if USB_HID_DEBUG then
                    serial_hw_data = " "
                    print_hex( TABLAT )
                end if

                asm TBLWT*
                start_write()
                asm TBLWT*+
            end loop

            usb_bd1in_cnt = 1

        end block

        UPDATE_LED:
        block

        end block

        RESET:
            block
                disable_boot()
                -- asm reset
                asm goto 0x800
            end block
    end case

    if usb_bd1in_cnt > 0 then
        -- if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if false then
            const byte str4[] = " XFER BYTES "
            print_string(serial_hw_data,str4)
            print_hex( usb_bd1in_cnt )
            serial_hw_data = " "
            serial_hw_data = "T"
            serial_hw_data = "0"
            serial_hw_data = " "
            print_hex( usb_bd1in_addrh )
            print_hex( usb_bd1in_addrl )

        end if
        trigger_dev2host_transfer()
    end if

    usb_prime_epx_out( end_point, USB_EP1_OUT_SIZE )

end procedure

include usb_drv

-- constants
-- const  byte str_welcome[] = "JAL USB BOOTLOADER 0.10\n"

-- variables

procedure usb_tasks() is
    pragma inline
    usb_handle_isr()
end procedure

-- interrupts? No thanks
-- INTCON_GIE = false

if defined( HAS_SERIAL_DEBUG_PORT ) == high then
    -- put info on RS-232 serial line
    serial_newline()
    serial_newline()

    -- print_string(serial_hw_data, str_welcome )
    serial_newline()
end if

procedure interrupt_high() is
    pragma interrupt raw
    asm goto ( 0x0808 )
end procedure

-- read first byte of USER ID
-- TBLPTRU = 0x20
-- TBLPTRH = 0x00
-- TBLPTRL = 0x00
--asm TBLRD*+

--if ( TABLAT != 0x00 ) then
-- if ( false) then
--	asm goto ( 0x800)
--else
    -- setup the USB device
    usb_setup()

    -- enable USB device
    usb_enable_module()
--end if

usb_bd1in_addr = USB_EP1_IN_ADDR

-- timer 1 on, prescaler 8
T1CON = 0b0011_0001

-- check if highest part of goto instruction
-- if byte is set to 0xFF, then disable
-- timer

TBLPTRU = 0x00
TBLPTRH = 0x08
TBLPTRL = 0x03

asm TBLRD*+
if TABLAT == 0xFF then
   T1CON = 0x00
end if

var byte t1_count = 0

-- main loop
forever loop
    -- poll the usb ISR function on a regular base, in order to
    -- serve the USB requests
    usb_handle_isr()
    if defined( HAS_SERIAL_DEBUG_PORT ) == true then
        if PIR1_RCIF then
        end if
    end if

    if PIR1_TMR1IF == 1 then
        t1_count = t1_count + 1
        PIR1_TMR1IF = 0

        -- if expired, then jump to user location
        if t1_count > BOOT_TIMER_TICS then
            disable_boot()

            -- start user app
            asm goto 0x800
        end if
    end if
end loop

Generated by JALlib CHM Help System | Source: usb_drv.jal


usb_tasks - JAL Language Syntax Reference

usb_tasks SYNTAX

Description:
This application implements the Microchip PDF/USB bootloader (legacy) -- The compiled code shall fit in the first 1024 words 0x0000..0x0800 -- The booloader checks the bootloader_program_pin, if it is low at initialization time -- the bootloader will be activated, otherwise the user program (starting at 0x800) is -- executed. Currently only the high priority interrupts are supported, since JAL does -- not support low priority interrupts. When the bootloader is active, he PDFSUSB utility -- can be used to program the flase (from 0x800 and onwards), eeprom and configuration data -- -- Sources: http://www.microchip.org for PICDEM specifications --

Notes

compiled with following flags -- use -no-variable-reuse when debugging flags are -- set due to a compiler issue -- -- ----------------------------------------------------- -- -- This file has been generated by jallib.py from: -- * board: board_18f4550_af.jal -- * test : test_usb_bootloader.jal -- -- whether or not using the serial port -- const HAS_SERIAL_DEBUG_PORT = 1 -- const STUB_ERASE = 1 -- const STUB_WRITE_FLASH = 1 ;@jallib section chipdef -- chip setup include 18f4550 -- even though the external crystal is 20 MHz, the configuration is such that -- the CPU clock is derived from the 96 Mhz PLL clock (div2), therefore set -- target frequency to 48 MHz pragma target clock 48_000_000 -- fuses pragma target PLLDIV P5 -- divide by 5 - 20MHZ_INPUT pragma target CPUDIV P1 -- [primary oscillator src: /1][96 mhz pll src: /2] pragma target USBDIV P2 -- CLOCK_SRC_FROM_96MHZ_PLL_2 pragma target OSC HS_PLL pragma target FCMEN DISABLED pragma target IESO DISABLED pragma target PWRTE DISABLED -- power up timer pragma target VREGEN ENABLED -- USB voltage regulator pragma target VOLTAGE V21 -- brown out voltage pragma target BROWNOUT DISABLED -- no brownout detection pragma target WDTPS P32K -- watch dog saler setting pragma target WDT CONTROL -- watchdog software controlled pragma target CCP2MUX pin_C1 -- CCP2 on pin C1 pragma target PBADEN DIGITAL -- digital input port<0..4> pragma target LPT1OSC LOW_POWER -- low power timer 1 pragma target MCLR EXTERNAL -- master reset on RE3 pragma target STVR DISABLED -- reset on stack over/under flow pragma target LVP ENABLED -- allow low-voltage programming pragma target XINST DISABLED -- extended instruction set pragma target DEBUG DISABLED -- background debugging pragma target CP0 DISABLED -- code block 0 not protected pragma target CP1 DISABLED -- code block 1 not protected pragma target CP2 DISABLED -- code block 2 not protected pragma target CP3 DISABLED -- code block 3 not protected pragma target CPB DISABLED -- bootblock code not write protected pragma target CPD DISABLED -- eeprom code not write protected pragma target WRT0 DISABLED -- table writeblock 0 not protected pragma target WRT1 DISABLED -- table write block 1 not protected pragma target WRT2 DISABLED -- table write block 2 not protected pragma target WRT3 DISABLED -- table write block 3 not protected pragma target WRTB DISABLED -- bootblock not write protected pragma target WRTD DISABLED -- eeprom not write protected pragma target WRTC DISABLED -- config not write protected pragma target EBTR0 DISABLED -- table read block 0 not protected pragma target EBTR1 DISABLED -- table read block 1 not protected pragma target EBTR2 DISABLED -- table read block 2 not protected pragma target EBTR3 DISABLED -- table read block 3 not protected pragma target EBTRB DISABLED -- boot block not protected WDTCON_SWDTEN = OFF -- disable watchdog ;@jallib section bootloader alias bootloader_program_pin is pin_b5 alias bootloader_program_pin_direction is pin_b5_direction const byte READ_VERSION = 0x00 const byte READ_FLASH = 0x01 const byte WRITE_FLASH = 0x02 const byte ERASE_FLASH = 0x03 const byte READ_EEDATA = 0x04 const byte WRITE_EEDATA = 0x05 const byte READ_CONFIG = 0x06 const byte WRITE_CONFIG = 0x07 const byte UPDATE_LED = 0x32 const byte RESET = 0xFF const byte MINOR_VERSION = 0x14 -- Bootloader Version 1.20 const byte MAJOR_VERSION = 0x01 if defined( HAS_SERIAL_DEBUG_PORT ) == true then const serial_hw_baudrate = 115_200 include serial_hardware include format include print -- intialze serial device serial_hw_init() -- uncomment when directly coupled (i.e. without max 232) to rs-232C -- BAUDCON_CKTXP = true procedure serial_print_spc() is serial_hw_write( " " ) end procedure procedure serial_newline() is serial_hw_write( 10 ) -- serial_hw_write( 13 ) end procedure procedure print_nibble( byte in nibble ) is if nibble > 9 then nibble = nibble + ( "A" - 10 ) else nibble = nibble + ( "0" ) end if serial_hw_data = nibble end procedure procedure print_hex( byte in bt ) is var byte nibble = bt >> 4 print_nibble( nibble ) nibble = bt & 0x0F print_nibble( nibble ) end procedure const bit USB_DEBUG = false const bit USB_HID_DEBUG = true const bit ADD_RW_OFFSET = true else const bit USB_DEBUG = false const bit USB_HID_DEBUG = false end if const bit USB_DEBUG_HIGH = USB_DEBUG const bit USB_HID_DEBUG_HIGH = USB_DEBUG include usb_defs const byte USB_EP0_OUT_SIZE = 8 const word USB_EP0_OUT_ADDR = ( USB_BASE_ADDRESS + 0x0010 ) const byte USB_EP0_IN_SIZE = 8 const word USB_EP0_IN_ADDR = ( USB_EP0_OUT_ADDR + USB_EP0_OUT_SIZE ) const bit USB_EP1 = 1 const byte USB_EP1_OUT_SIZE = 64 const word USB_EP1_OUT_ADDR = ( USB_EP0_IN_ADDR + USB_EP0_IN_SIZE ) const byte USB_EP1_IN_SIZE = USB_EP1_OUT_SIZE const word USB_EP1_IN_ADDR = USB_EP1_OUT_ADDR -- point to the same buffer! var volatile byte usb_ep1in_buf[ USB_EP1_IN_SIZE ] at USB_EP1_IN_ADDR var volatile byte usb_ep1out_buf[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR var volatile byte boot_cmd_buffer[ USB_EP1_OUT_SIZE ] at USB_EP1_OUT_ADDR -- ********************************************************************* -- * General Data Packet Structure: -- * . -- * __________________ boot_cmd fields -- * | COMMAND | 0 [CMD] -- * | LEN | 1 [LEN] -- * | ADDRL | 2 [ ] [addrl] -- * | ADDRH | 3 [ADR.pAdr]: [addrh] -- * | ADDRU | 4 [ ] [addru] -- * | | 5 [DATA] -- * | | -- * . DATA . -- * . . -- * | | 62 -- * |________________| 63 -- * -- ********************************************************************/ var volatile byte boot_cmd_cmd at boot_cmd_buffer[0] var volatile byte boot_cmd_len at boot_cmd_buffer[1] var volatile byte boot_cmd_addrl at boot_cmd_buffer[2] var volatile byte boot_cmd_addrh at boot_cmd_buffer[3] var volatile byte boot_cmd_addru at boot_cmd_buffer[4] var volatile byte boot_cmd_data[USB_EP1_OUT_SIZE-6] at boot_cmd_buffer[5] const bit USB_EP2 = 0 const byte USB_EP2_OUT_SIZE = 8 const word USB_EP2_OUT_ADDR = 0x0000 const byte USB_EP2_IN_SIZE = 8 const word USB_EP2_IN_ADDR = 0x0000 const bit USB_EP3 = 0 const byte USB_EP3_OUT_SIZE = 8 const word USB_EP3_OUT_ADDR = 0x0000 const byte USB_EP3_IN_SIZE = 8 const word USB_EP3_IN_ADDR = 0x0000 const byte USB_DEVICE_DESCRIPTOR[USB_DEVICE_DESCRIPTOR_SIZE] = { USB_DEVICE_DESCRIPTOR_SIZE, -- 18 bytes long USB_DT_DEVICE, -- DEVICE 01h 0x00, 0x02, -- usb version 2.00 0x00, -- class 0x00, -- subclass 0x00, -- protocol USB_EP0_OUT_SIZE, -- max packet size for end point 0 0xd8, 0x04, -- Microchip's vendor 0x0b, 0x00, -- Microchip bootloader 0x01, 0x00, -- version 1.0 of the product 0x00, -- string 1 for manufacturer 0x00, -- string 2 for product 0x00, -- string 3 for serial number 0x01 -- number of configurations } const USB_CONFIGURATION_DESCRIPTOR_SIZE = 0x09 + 0x09 + 0x07 + 0x07 const byte USB_CONFIGURATION_DESCRIPTOR[ USB_CONFIGURATION_DESCRIPTOR_SIZE ]= { -- configuration descriptor - - - - - - - - - - 0x09, -- length, USB_DT_CONFIGURATION, -- descriptor_type USB_CONFIGURATION_DESCRIPTOR_SIZE, 0x00, -- total_length; 0x01, -- num_interfaces, 0x01, -- configuration_value, 0x00, -- configuration_string_id, 0b10000000, -- attributes (bus powered, no remote wake up) 100, -- max_power; (200ma) -- interface descriptor - - - - - - - - - - - - 0x09, -- length, USB_DT_INTERFACE, -- descriptor_type, 0x00, -- interface_number, (starts at zero) 0x00, -- alternate_setting, (no alternatives) 0x02, -- num_endpoints, 0x00, -- interface_class, 0x00, -- interface_subclass, 0x00, -- interface_protocol, 0x00, -- interface_string_id; -- endpoint descriptor(s) - - - - - - - - - - - - 0x07, -- length, USB_DT_ENDPOINT, -- descriptor_type, 0b10000001, -- endpoint_address, (Endpoint 1, IN) USB_EPT_BULK, -- attributes USB_EP1_IN_SIZE, 0x00, -- max_packet_size 0x00, -- interval 0x07, -- length, USB_DT_ENDPOINT, -- descriptor_type, 0b00000001, -- endpoint_address, (Endpoint 1, OUT) USB_EPT_BULK, -- attributes USB_EP1_OUT_SIZE, 0x00, -- max_packet_size 0x00 -- interval } const byte USB_STRING0[] = { 0x04, -- bLength USB_DT_STRING, -- bDescriptorType 0x09, -- wLANGID[0] (low byte) 0x04 -- wLANGID[0] (high byte) } include usb_drv_core

Example

procedure trigger_dev2host_transfer() is
    var volatile bit dts_bit at usb_bd1in_stat : USB_BDSTATUS_DTS
--	var volatile bit uown_bit_out at usb_bd1in_stat : USB_BDSTATUS_UOWN

    if ( dts_bit  ) then
        usb_bd1in_stat = 0b_1000_1000
    else
        usb_bd1in_stat = 0b_1100_1000
    end if

Generated by JAL Syntax Documentation System | Source: DITA


ush_keyboard_send_key - JALlib Procedures Help

ush_keyboard_send_key JALLIB PROCEDURE

Signature

procedure ush_keyboard_send_key( byte in modifier_key, byte in key ) is

Description

ush_keyboard_send_key - send a key code (blocking!)
ush_keyboard_send_key() sends a key code toward the USB HID host
the call is blocking and assumes that the HID communcation channel
has been established. See also definitions for key codes (starting
with USB_KEYBOARD_KEY_xxxx) and for the modifier key definitions
starting with USB_KEYBOARD_MKEY_. Note that once a key code has been
send, the HID host assumes that the key remains pressed, until a
USB_KEYBOARD_KEY_NONE (or other key) is send towards the HID host

Include

To use this procedure, include the library:

include usb_keyboard

Parameters

  • modifier_key - byte in
  • key - byte in

Return Value

None

Example

From sample file: 16f1455_usb_hid_keyboard.jal

-- -----------------------------------------------------------------------------
-- Title: USB HID keyboard device demo for the PIC16F1455
-- Author: Rob Jansen, Copyright (c) 2018..2021, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This application emulates a keyboard USB human interface device
-- (HID), once the USB device has been conifgured and the USB HID device is recognized by
-- the host operating systems, it will generate keyboard chars if boot program pin is low
--
-- Sources: http://www.usb.org for USB specifications
--
-- Notes: There are two options to use the USB driver:
--        1) Without interrupts by frequently calling 'usb_keyboard_flush()'
--           frequently in the main loop.
--        2) Using interrupts to make timing less critical. In that case no
--           calls to 'usb_keyboard_flush()' are needed.
--           This can be activated by defining: const USB_INTERRUPT_DRIVEN = TRUE
--
-- ------------------------------------------------------
--
-- This file was orginally copied from 18f14k50_hid_keyboard.jal and made
-- operational to work for the PIC16F1454/55/59 using the modified usb driver.
--

include 16f1455

-- For hardware a 14 pin DIL PIC16F1455 was used. The circuit can be powered by
-- the USB connection and connected as follows:
-- *) USB data- wire to pin 12 (D-)
-- *) USB data+ wire to pin 13 (D+)
-- *) USB power wire to pin 1 (Vdd). Don't forget 100nF decoupling capacitor.
-- *) USB ground wire to pin 14 (Vss)
-- *) A resistor of 33kOhm to pin 4 (MCLR) and power. We use internal reset.
-- *) A capacitor of 220nF to pin 11 (Vusb3v3) and ground.
-- *) A crystal of 12 MHz to pin 2 and pin 3 with 2*18 pF capacitors to ground.
-- Settings are also given to use the internal oscilator of the PIC so no need
-- for the 12 MHz crystal which saves you a crystal and 2 pins on the chip.
-- The configuration runs at an internal clock of 48 MHz.
-- Two additional indication LEDs are connected, see definition below.

pragma target clock       48_000_000

-- Compiler options.
pragma warn all no              -- We do not want to know all compiler warnings
pragma opt variable_reduce yes

-- fuses
-- Settings for external 12 MHz crystal and system clock 48 MHz.
pragma target OSC           HS       -- External crystal
pragma target CLKOUTEN      ENABLED  -- CLKOUT function is enabled
pragma target PLLMULT       N4X      -- PLL Multipler Selection Bit, 4x Output Frequency Selected

-- Settings for internal clock and system clock 48 MHz.
--pragma target OSC           INTOSC_NOCLKOUT -- Internal clock
--pragma target CLKOUTEN      DISABLED -- CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin
--pragma target PLLMULT       N3X      -- PLL Multipler Selection Bit, 3x Output Frequency Selected

-- Other fuses
pragma target CPUDIV        P1       -- NO CPU system divide
pragma target USBLSCLK      F48MHZ   -- System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.
pragma target PLLEN         ENABLED  -- 3x or 4x PLL Enabled
pragma target FCMEN         DISABLED -- Fail-Safe Clock Monitor is disabled
pragma target WRT           DISABLED -- Write protection off
pragma target STVR          ENABLED  -- Stack Overflow or Underflow will cause a Reset
pragma target LPBOR         DISABLED -- Low-Power BOR is disabled
pragma target IESO          DISABLED -- Internal/External Switchover Mode is disabled
pragma target PWRTE         DISABLED -- power up timer
pragma target BROWNOUT      DISABLED -- no brownout detection
pragma target WDT           DISABLED -- Watchdog disabled
pragma target MCLR          EXTERNAL -- Exyzabternal reset
pragma target LVP           DISABLED -- no low-voltage programming
pragma target VOLTAGE       MAXIMUM  -- brown out voltage
pragma target CP            DISABLED -- Program memory code protection is disabled

OSCCON        = 0b1111_1100          -- Select PLL,3x, 16MHz internal oscillator

-- Enable weak pull-up for port a.
OPTION_REG_WPUEN = FALSE             -- Enable weak pull-up for port a.
WPUA          = 0b0011_1000          -- Weak-pull up for relevant port a bits.

include delay

-- Pin definitions.
alias bootloader_program_pin is pin_c2  -- Pin 8.
alias bootloader_program_pin_direction  is pin_c2_direction

-- LED IO definition
alias led             is pin_c3         -- Pin 7.
alias led_direction   is pin_c3_direction
alias led2            is pin_c4         -- Pin 6.
alias led2_direction  is pin_c4_direction

-- Use the USB driver on an interrupt basis. This makes it possible to use
-- delays in the main loop since timing becomes less critical.
const USB_INTERRUPT_DRIVEN = TRUE
include usb_keyboard

-- set all inputs to digital
enable_digital_io()

-- setup direction bits
led_direction = output
led2_direction = output
bootloader_program_pin_direction = input

var byte key_value = USB_KEYBOARD_KEY_A

-- intialize the library
usb_keyboard_init()

-- main loop
forever loop

   if !defined(USB_INTERRUPT_DRIVEN) then
      -- When the interrupt mode is not used we need to poll the usb ISR function
      -- on a regular base, in order to serve the USB requests otherwise
      -- this call can be removed.
      usb_keyboard_flush()
   end if

   -- check if USB device has been configured by the HOST
   if usb_is_configured()  then

      led = usb_keyboard_led_caps_lock
      led2 = usb_keyboard_led_num_lock

      if ( bootloader_program_pin == low )then
      -- send key code towards the USB host
      -- ush_keyboard_send_key( USB_KEYBOARD_MKEY_LEFT_SHIFT, key_value )
      ush_keyboard_send_key( 0x00, key_value )

      -- next key code
      key_value = key_value + 1
      if ( key_value > USB_KEYBOARD_KEY_Z ) then
         key_value = USB_KEYBOARD_KEY_A
      end if
   else
      -- depress key
      ush_keyboard_send_key( 0, 0 )
   end if

      -- debounce switch
      delay_1ms(50)
   end if

end loop

Generated by JALlib CHM Help System | Source: usb_keyboard.jal


Variables - JAL Language Syntax Reference

Variables JALV2 SYNTAX

Syntax

VAR [VOLATILE] [SHARED] type[*

Description

A variable is simply an identifier that holds a value. These identifiers have types associated which define how much space is required to hold the value. The following types are built-in: The complete format for defining a variable is: This is, by far, the most complex construct in all of JAL, so I'll describe it one piece at a time below. Once variable definition is understood, everything else is easy! VAR VOLATILE SHARED type[* '[' [ AT AT AT '{' IS '=' '=' '{' '=' '"' ... '"' '=' "..." ',

          VAR BIT*2 cc
          cc = (value & 0x03)
          VAR BYTE fixed_variable at 0x20
          VAR BYTE data
          VAR BIT data_bit at data:0 -- Overlay
          VAR WORD channel_word
          VAR BYTE channel_byte[2] at channel_word -- Overlay
          VAR DOWRD base_data
          VAR BYTE low_byte at base_data+0
          VAR BYTE high_byte at base_data+1
          VAR WORD upper_word at base_data+2
          VAR BYTE a,b,c

Generated by JAL Syntax Documentation System | Source: DITA


Variables, Constants, Aliases - JAL Language Syntax Reference

Variables, Constants, Aliases JALV2 SYNTAX

Description

Generated by JAL Syntax Documentation System | Source: DITA


virtual_wire.jal - JALLIB Library Documentation

virtual_wire.jal JALLIB LIBRARY

Title

Virtual Wire

Author

Rob Jansen, Copyright (c) 2018..2019, all rights reserved., Adapted-by:

Compiler

2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library for sending and receiving data over an RF Link based
on Virtual Wire. The driver implements a Phase Locked Loop to
increase sensitivity and so extend the range of the connection.
Next to that it uses a special encoding format for the bit
pattern to stay DC neutral. See sources for more information
on Virtual Wire.
A standard 433 MHz transmitter and 433 MHz receiver was used
for testing this driver using a maximum bitrate of 2000 bits/s.
In order to use this driver the main program must have the
following defined (this to make this driver PIC independent):
-) An alias for the tranmission pin vw_tx_pin.
-) An alias for the receive pin vw_rx_pin.
-) Initializing a timer that is used for transmission and
reception. The timer must run at 8 times the bitrate.
-) An interrupt routine of the used timer which must call the
vw_service() procedure.
A transmitter only and receiver only version is also available
to save data space and code space for use in smaller PICs.
Note that you have to define a vw_tx_pin and and vw_rx_pin in
order to be able to use this library.
Dependencies: -

Notes

Changes to the original driver that was created for Arduino:
*) From C converted to JAL. This required an extra receive buffer because
of the lack of pointers which could not pass a receive buffer.
*) The inverting of the output and input signal was removed.
*) The 6 to 4 conversion was changed into a look-up table to improve speed.
*) The maximum message length was reduced to 10 to save data space but can
be changed by the user by setting VW_MAX_MESSAGE_LEN to another value.
*) The transmission header was moved from data to constant as to decrease
the size of the transmit buffer and so save data space.
*) The transmission buffer and reception buffer were combined into one
buffer to save data space. This can be done since the original driver does
not support transmission and reception at the same time.
*) The bit rate is defined by the user by initializing the used timer.
-------------------------------- Pins ---------------------------------------
A transmit pin must be defined by the main program.

A receive pin must be defined by the main program. Note. Do not enable
weak-pull up on this pin since the receiver may not be able to pull it down.

------------------ Public functions and procedurs --------------------------------

Initialize the virtual wire driver.

Sources

http://www.airspayce.com/mikem/arduino/VirtualWire.pdf

Constants and Variables

VW_MAX_MESSAGE_LEN - const byte = VW_MESSAGE_BUFFER + 3
VW_MAX_MESSAGE_LEN - const byte = 10
VW_RX_SAMPLES_PER_BIT - const byte = 8
VW_MAX_PAYLOAD - const byte = VW_MAX_MESSAGE_LEN - 3
VW_RX_RAMP_LEN - const byte = 160
VW_RAMP_INC - const byte = (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
VW_RAMP_TRANSITION - const byte = VW_RX_RAMP_LEN/2
VW_RAMP_ADJUST - const byte = 9
VW_RAMP_INC_RETARD - const byte = (VW_RAMP_INC - VW_RAMP_ADJUST)
VW_RAMP_INC_ADVANCE - const byte = (VW_RAMP_INC + VW_RAMP_ADJUST)
VW_HEADER_LEN - const byte = 8
vw_tx_len - var byte
vw_tx_index - var byte
vw_tx_bit - var byte
vw_tx_sample - var byte
vw_tx_enabled - var bit
vw_tx_header - var bit
vw_rx_sample - var bit
vw_rx_last_sample - var bit
vw_rx_pll_ramp - var byte
vw_rx_integrator - var byte
vw_rx_active - var bit
vw_rx_done - var bit
vw_rx_enabled - var bit
vw_rx_bits - var word
vw_rx_bit_count - var byte
vw_rx_count - var byte
vw_rx_len - var byte
vw_rx_bad - var dword
vw_rx_good - var dword

Routines

  • _vw_calc_crc - Function returns word
  • _vw_pll - Procedure
  • vw_get_message - Function returns bit
  • vw_get_rx_bad - Function returns dword
  • vw_get_rx_good - Function returns dword
  • vw_have_message - Function returns bit
  • vw_init - Procedure
  • vw_reset_rx_good_bad_count - Procedure
  • vw_rx_start - Procedure
  • vw_rx_stop - Procedure
  • vw_send - Function returns bit
  • vw_service - Procedure
  • vw_tx_active - Function returns bit
  • vw_tx_stop - Procedure
  • vw_wait_rx - Procedure
  • vw_wait_tx - Procedure


virtual_wire_receiver.jal - JALLIB Library Documentation

virtual_wire_receiver.jal JALLIB LIBRARY

Title

Virtual Wire receiver only version

Author

Rob Jansen, Copyright (c) 2018..2019, all rights reserved., Adapted-by:

Compiler

2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This is the receive only version of Virtual_Wire, see the file
virtual_wire.jal for all changes compared to the original
Virtual_Wire library and more information.
Dependencies: -

Notes

-
-------------------------------- Pins ---------------------------------------

A receive pin must be defined by the main program. Note. Do not enable
weak-pull up on this pin since the receiver may not be able to pull it down.

------------------ Public functions and procedurs --------------------------------
Initialize the virtual wire driver.

Sources

http://www.airspayce.com/mikem/arduino/VirtualWire.pdf

Constants and Variables

VW_MAX_MESSAGE_LEN - const byte = VW_MESSAGE_BUFFER + 3
VW_MAX_MESSAGE_LEN - const byte = 10
VW_RX_SAMPLES_PER_BIT - const byte = 8
VW_MAX_PAYLOAD - const byte = VW_MAX_MESSAGE_LEN - 3
VW_RX_RAMP_LEN - const byte = 160
VW_RAMP_INC - const byte = (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
VW_RAMP_TRANSITION - const byte = VW_RX_RAMP_LEN/2
VW_RAMP_ADJUST - const byte = 9
VW_RAMP_INC_RETARD - const byte = (VW_RAMP_INC - VW_RAMP_ADJUST)
VW_RAMP_INC_ADVANCE - const byte = (VW_RAMP_INC + VW_RAMP_ADJUST)
vw_rx_sample - var bit
vw_rx_last_sample - var bit
vw_rx_pll_ramp - var byte
vw_rx_integrator - var byte
vw_rx_active - var bit
vw_rx_done - var bit
vw_rx_enabled - var bit
vw_rx_bits - var word
vw_rx_bit_count - var byte
vw_rx_count - var byte
vw_rx_len - var byte

Routines

  • _vw_calc_crc - Function returns word
  • _vw_pll - Procedure
  • vw_get_message - Function returns bit
  • vw_have_message - Function returns bit
  • vw_init - Procedure
  • vw_rx_start - Procedure
  • vw_rx_stop - Procedure
  • vw_service - Procedure
  • vw_wait_rx - Procedure


virtual_wire_transmitter.jal - JALLIB Library Documentation

virtual_wire_transmitter.jal JALLIB LIBRARY

Title

Virtual Wire transmitter only version

Author

Rob Jansen, Copyright (c) 2018..2019, all rights reserved., Adapted-by:

Compiler

2.5r2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

This is the transmit only version of Virtual_Wire, see the file
virtual_wire.jal for all changes compared to the original
Virtual_Wire library and more information.
Dependencies: -

Notes

-
-------------------------------- Pins ---------------------------------------

A transmit pin must be defined by the main program.

------------------ Public functions and procedurs --------------------------------
Initialize the virtual wire driver.

Sources

http://www.airspayce.com/mikem/arduino/VirtualWire.pdf

Constants and Variables

VW_MAX_MESSAGE_LEN - const byte = VW_MESSAGE_BUFFER + 3
VW_MAX_MESSAGE_LEN - const byte = 10
VW_RX_SAMPLES_PER_BIT - const byte = 8
VW_MAX_PAYLOAD - const byte = VW_MAX_MESSAGE_LEN - 3
VW_RX_RAMP_LEN - const byte = 160
VW_RAMP_INC - const byte = (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
VW_RAMP_TRANSITION - const byte = VW_RX_RAMP_LEN/2
VW_RAMP_ADJUST - const byte = 9
VW_RAMP_INC_RETARD - const byte = (VW_RAMP_INC - VW_RAMP_ADJUST)
VW_RAMP_INC_ADVANCE - const byte = (VW_RAMP_INC + VW_RAMP_ADJUST)
VW_HEADER_LEN - const byte = 8
vw_tx_len - var byte
vw_tx_index - var byte
vw_tx_bit - var byte
vw_tx_sample - var byte
vw_tx_enabled - var bit
vw_tx_header - var bit

Routines

  • _vw_calc_crc - Function returns word
  • vw_init - Procedure
  • vw_send - Function returns bit
  • vw_service - Procedure
  • vw_tx_active - Function returns bit
  • vw_tx_stop - Procedure
  • vw_wait_tx - Procedure


vl53l0x.jal - JALLIB Library Documentation

vl53l0x.jal JALLIB LIBRARY

Title

VL53L0X Time-of-Flight ranging sensor library.

Author

Rob Jansen, Copyright (c) 2025..2025, all rights reserved., Adapted-by:

Compiler

2.5r9

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Libray for the VL53L0X Time-of-Flight ranging sensor. It is controlled
using the IIC interface at a maximum speed of 400 kHz.

Notes

The main program must initialize the used - default - IIC interface
with a maximum speed of 400 kHz and with a I2C_HARDWARE_TIMEOUT
defined.
Info about the vl53l0x module:
-) Operated at 5 volt due to an on-board voltage regulator of 2.8 Volt.
-) Has an on-board level shifter for the IIC signals for 5 Volt operation,
including the required IIC pull-up resistors.
-) Has a shutdown input pin which is NOT 5 Volt tolerant. Shutdown can
be activated by pulling this pin low using an open drain pin.
This pin is pulled-up high by an on-board resistor to the internal VDD
of 2.8 Volt so the module is active when not connected.
-) Has an GPIO pin which is pulled-up high by an on-board resistor to the
internal VDD of 2.8 Volt and is open drain. It is used to generate an
interrupt after a measurement is done. The pin is NOT 5 Volt tolerant
so when used connect it to a level shifter or via a transistor.

-----------------------------------------------------------------------------
---------------------- PUBLIC CONSTANTS DEFS --------------------------------
-----------------------------------------------------------------------------
Default IIC address of the VL53L0X, LSB is read/write bit. This address is
used by the VL53L0X module after power up.

Sources

Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
Datasheet STMicroelectronics VL53L0X DS11555 - Rev 6

Constants and Variables

VL53L0X_IIC_DEFAULT_ADDRESS - const byte = 0x52
VL53L0X_VCSEL_PERIOD_PRE_RANGE - const byte = 0
VL53L0X_VCSEL_PERIOD_FINAL_RANGE - const byte = 1
timeout_counter - var word
temp - var byte
macro_period_ns - var dword = _vl53l0x_calc_period(vcsel_period_pclks)
macro_period_ns - var dword = _vl53l0x_calc_period(vcsel_period_pclks)

Routines

  • _vl53l0x_calc_period - Function returns dword
  • _vl53l0x_decode_timeout - Function returns word
  • _vl53l0x_decode_vcsel_period - Function returns byte
  • _vl53l0x_encode_timeout - Function returns word
  • _vl53l0x_encode_vcsel_period - Function returns byte
  • _vl53l0x_get_sequence_step_enables - Procedure
  • _vl53l0x_get_sequence_step_timeouts - Procedure
  • _vl53l0x_get_spad_info - Function returns bit
  • _vl53l0x_perform_single_ref_calibration - Function returns bit
  • _vl53l0x_read_data_byte - Function returns byte
  • _vl53l0x_read_data_dword - Function returns dword
  • _vl53l0x_read_data_word - Function returns word
  • _vl53l0x_read_spad_map - Procedure
  • _vl53l0x_timeout_mclks_to_microseconds - Function returns dword
  • _vl53l0x_timeout_microseconds_to_mclks - Function returns dword
  • _vl53l0x_write_data_byte - Procedure
  • _vl53l0x_write_data_dword - Procedure
  • _vl53l0x_write_data_word - Procedure
  • _vl53l0x_write_spad_map - Procedure
  • vl53l0x_get_iic_address - Function returns byte
  • vl53l0x_get_measurement_timing_budget - Function returns dword
  • vl53l0x_get_signal_rate_limit - Function returns word
  • vl53l0x_get_timeout - Function returns word
  • vl53l0x_get_vcsel_pulse_period - Function returns byte
  • vl53l0x_init - Function returns bit
  • vl53l0x_read_range_continuous_mil - Function returns word
  • vl53l0x_read_range_continuous_millimeters - Function returns word
  • vl53l0x_read_range_single_mil - Function returns word
  • vl53l0x_read_range_single_millimeters - Function returns word
  • vl53l0x_set_iic_address - Procedure
  • vl53l0x_set_measurement_timing_budget - Function returns bit
  • vl53l0x_set_signal_rate_limit - Function returns bit
  • vl53l0x_set_timeout - Procedure
  • vl53l0x_set_vcsel_pulse_period - Function returns bit
  • vl53l0x_start_continuous - Procedure
  • vl53l0x_stop_continuous - Procedure
  • vl53l0x_timeout_occured - Function returns bit
  • vl53l0x_valid_module - Function returns bit


vl53l0x_get_iic_address - JALlib Procedures Help

vl53l0x_get_iic_address JALLIB FUNCTION

Signature

function vl53l0x_get_iic_address() return byte is

Description

Get the IIC address of the VL53L0X module.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

byte - Function return value

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_get_timeout - JALlib Procedures Help

vl53l0x_get_timeout JALLIB FUNCTION

Signature

function vl53l0x_get_timeout() return word is

Description

Get the current response timeout in ms.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_init - JALlib Procedures Help

vl53l0x_init JALLIB FUNCTION

Signature

function vl53l0x_init() return bit is

Description

Initialize sensor using sequence based on VL53L0X_DataInit(),
VL53L0X_StaticInit(), and VL53L0X_PerformRefCalibration().
This function does not perform reference SPAD calibration
(VL53L0X_PerformRefSpadManagement()), since the API user manual says that it
is performed by ST on the bare modules. It seems like that should work well
enough unless a cover glass is added. We use the 2V8 mode since at power up
the module is in 1V8 mode. At initialization the module ID is checked.
Returns TRUE if initialization was succesful.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_read_range_continuous_mil - JALlib Procedures Help

vl53l0x_read_range_continuous_mil JALLIB FUNCTION

Signature

function vl53l0x_read_range_continuous_mil() return word is

Description

Returns a range reading in mil when continuous mode is active. Calls
vl53l0x_read_range_continuous_millimeters() and converts it to mils.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_read_range_continuous_millimeters - JALlib Procedures Help

vl53l0x_read_range_continuous_millimeters JALLIB FUNCTION

Signature

function vl53l0x_read_range_continuous_millimeters() return word is

Description

Returns a range reading in millimeters when continuous mode is active
(readRangeSingleMillimeters() also calls this function after starting a
single-shot range measurement).

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_read_range_single_mil - JALlib Procedures Help

vl53l0x_read_range_single_mil JALLIB FUNCTION

Signature

function vl53l0x_read_range_single_mil() return word is

Description

Performs a single-shot range measurement and returns the reading in mil.
Calls vl53l0x_read_range_single_millimeters() and converts it to mil.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_vl53l0x_single.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using single shot range.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Variables.
var word distance
var bit all_ok

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Use vl53l0x_set_timeout() to increase the timeout value.\r\n")
   print_string(serial, "Or check your IIC connection.\r\n")

end procedure

-- Uncomment this line to use long range mode. This increases the sensitivity
-- of the sensor and extends its potential range, but increases the
-- likelihood of getting an inaccurate reading because of reflections from
-- objects other than the intended target. It works best in dark conditions.
-- const LONG_RANGE = TRUE

-- Uncomment ONE of these two lines to get:
-- -) Higher speed at the cost of lower accuracy OR
-- -) Higher accuracy at the cost of lower speed
-- const HIGH_SPEED = TRUE
-- const HIGH_ACCURACY = TRUE

-- If needed, change IIC address:
-- const NEW_IIC_ADDRESS = TRUE
-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

if defined(LONG_RANGE) then
   -- Lower the return signal rate limit (default is 0.25 MCPS)
   -- to 0.1 MCPS.  Note that we use the value * 100 so 0.1 equals 10.
   all_ok = vl53l0x_set_signal_rate_limit(10)
   -- Increase laser pulse periods (defaults are 14 and 10 PCLKs).
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18)
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14)
   if !all_ok then
      print_string(serial, "Could not set long range.\r\n")
   end if
end if

if defined(HIGH_SPEED) then
   -- Reduce timing budget to 20 ms (default is about 33 ms).
   if !vl53l0x_set_measurement_timing_budget(20_000) then
      print_string(serial, "Could not set high speed.\r\n")
   end if
elsif defined(HIGH_ACCURACY) then
   -- Increase timing budget to 200 ms.
   if !vl53l0x_set_measurement_timing_budget(200_000) then
      print_string(serial, "Could not set high accuracy.\r\n")
   end if
end if

forever  loop

   ; Start with measurement in mm.
   distance =  vl53l0x_read_range_single_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance =  vl53l0x_read_range_single_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_read_range_single_millimeters - JALlib Procedures Help

vl53l0x_read_range_single_millimeters JALLIB FUNCTION

Signature

function vl53l0x_read_range_single_millimeters() return word is

Description

Performs a single-shot range measurement and returns the reading in
millimeters. Based on VL53L0X_PerformSingleRangingMeasurement().

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

word - Function return value

Example

From sample file: 16f1825_vl53l0x_single.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using single shot range.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Variables.
var word distance
var bit all_ok

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Use vl53l0x_set_timeout() to increase the timeout value.\r\n")
   print_string(serial, "Or check your IIC connection.\r\n")

end procedure

-- Uncomment this line to use long range mode. This increases the sensitivity
-- of the sensor and extends its potential range, but increases the
-- likelihood of getting an inaccurate reading because of reflections from
-- objects other than the intended target. It works best in dark conditions.
-- const LONG_RANGE = TRUE

-- Uncomment ONE of these two lines to get:
-- -) Higher speed at the cost of lower accuracy OR
-- -) Higher accuracy at the cost of lower speed
-- const HIGH_SPEED = TRUE
-- const HIGH_ACCURACY = TRUE

-- If needed, change IIC address:
-- const NEW_IIC_ADDRESS = TRUE
-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

if defined(LONG_RANGE) then
   -- Lower the return signal rate limit (default is 0.25 MCPS)
   -- to 0.1 MCPS.  Note that we use the value * 100 so 0.1 equals 10.
   all_ok = vl53l0x_set_signal_rate_limit(10)
   -- Increase laser pulse periods (defaults are 14 and 10 PCLKs).
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18)
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14)
   if !all_ok then
      print_string(serial, "Could not set long range.\r\n")
   end if
end if

if defined(HIGH_SPEED) then
   -- Reduce timing budget to 20 ms (default is about 33 ms).
   if !vl53l0x_set_measurement_timing_budget(20_000) then
      print_string(serial, "Could not set high speed.\r\n")
   end if
elsif defined(HIGH_ACCURACY) then
   -- Increase timing budget to 200 ms.
   if !vl53l0x_set_measurement_timing_budget(200_000) then
      print_string(serial, "Could not set high accuracy.\r\n")
   end if
end if

forever  loop

   ; Start with measurement in mm.
   distance =  vl53l0x_read_range_single_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance =  vl53l0x_read_range_single_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_set_iic_address - JALlib Procedures Help

vl53l0x_set_iic_address JALLIB PROCEDURE

Signature

procedure vl53l0x_set_iic_address(byte in address) is

Description

Set the IIC address of the VL53L0X to the given address.
The default after power up is: VL53L0X_IIC_DEFAULT_ADDRESS

Include

To use this procedure, include the library:

include vl53l0x

Parameters

  • address - byte in

Return Value

None

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_set_measurement_timing_budget - JALlib Procedures Help

vl53l0x_set_measurement_timing_budget JALLIB FUNCTION

Signature

function vl53l0x_set_measurement_timing_budget(dword in budget_us) return bit is

Description

Set the measurement timing budget in microseconds, which is the time allowed
for one measurement; the ST API and this library take care of splitting the
timing budget among the sub-steps in the ranging sequence. A longer timing
budget allows for more accurate measurements. Increasing the budget by a
factor of N decreases the range measurement standard deviation by a factor
of sqrt(N). Defaults to about 33 milliseconds; the minimum is 20 ms.
based on VL53L0X_set_measurement_timing_budget_micro_seconds()
Returns TRUE when succesfull.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

  • budget_us - dword in

Return Value

bit - Function return value

Example

From sample file: 16f1825_vl53l0x_single.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using single shot range.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Variables.
var word distance
var bit all_ok

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Use vl53l0x_set_timeout() to increase the timeout value.\r\n")
   print_string(serial, "Or check your IIC connection.\r\n")

end procedure

-- Uncomment this line to use long range mode. This increases the sensitivity
-- of the sensor and extends its potential range, but increases the
-- likelihood of getting an inaccurate reading because of reflections from
-- objects other than the intended target. It works best in dark conditions.
-- const LONG_RANGE = TRUE

-- Uncomment ONE of these two lines to get:
-- -) Higher speed at the cost of lower accuracy OR
-- -) Higher accuracy at the cost of lower speed
-- const HIGH_SPEED = TRUE
-- const HIGH_ACCURACY = TRUE

-- If needed, change IIC address:
-- const NEW_IIC_ADDRESS = TRUE
-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

if defined(LONG_RANGE) then
   -- Lower the return signal rate limit (default is 0.25 MCPS)
   -- to 0.1 MCPS.  Note that we use the value * 100 so 0.1 equals 10.
   all_ok = vl53l0x_set_signal_rate_limit(10)
   -- Increase laser pulse periods (defaults are 14 and 10 PCLKs).
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18)
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14)
   if !all_ok then
      print_string(serial, "Could not set long range.\r\n")
   end if
end if

if defined(HIGH_SPEED) then
   -- Reduce timing budget to 20 ms (default is about 33 ms).
   if !vl53l0x_set_measurement_timing_budget(20_000) then
      print_string(serial, "Could not set high speed.\r\n")
   end if
elsif defined(HIGH_ACCURACY) then
   -- Increase timing budget to 200 ms.
   if !vl53l0x_set_measurement_timing_budget(200_000) then
      print_string(serial, "Could not set high accuracy.\r\n")
   end if
end if

forever  loop

   ; Start with measurement in mm.
   distance =  vl53l0x_read_range_single_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance =  vl53l0x_read_range_single_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_set_signal_rate_limit - JALlib Procedures Help

vl53l0x_set_signal_rate_limit JALLIB FUNCTION

Signature

function vl53l0x_set_signal_rate_limit(word in rate_limit) return bit is

Description

Set the return signal rate limit check value in units of MCPS (million counts
per second). "This represents the amplitude of the signal reflected from the
target and detected by the device"; setting this limit presumably determines
the minimum measurement necessary for the sensor to report a valid reading.
Setting a lower limit increases the potential range of the sensor but also
seems to increase the likelihood of getting an inaccurate reading because of
unwanted reflections from objects other than the intended target.
The rate limit is given in 100 * MCPS and must be < 51_200. Reason for
using 100 * MCPS is that we do not need to use float but instead use word.
Defaults to 25 (= 0.25 MCPS) as initialized by the ST API and this library.
Returns TRUE when succesful.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

  • rate_limit - word in

Return Value

bit - Function return value

Example

From sample file: 16f1825_vl53l0x_single.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using single shot range.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Variables.
var word distance
var bit all_ok

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Use vl53l0x_set_timeout() to increase the timeout value.\r\n")
   print_string(serial, "Or check your IIC connection.\r\n")

end procedure

-- Uncomment this line to use long range mode. This increases the sensitivity
-- of the sensor and extends its potential range, but increases the
-- likelihood of getting an inaccurate reading because of reflections from
-- objects other than the intended target. It works best in dark conditions.
-- const LONG_RANGE = TRUE

-- Uncomment ONE of these two lines to get:
-- -) Higher speed at the cost of lower accuracy OR
-- -) Higher accuracy at the cost of lower speed
-- const HIGH_SPEED = TRUE
-- const HIGH_ACCURACY = TRUE

-- If needed, change IIC address:
-- const NEW_IIC_ADDRESS = TRUE
-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

if defined(LONG_RANGE) then
   -- Lower the return signal rate limit (default is 0.25 MCPS)
   -- to 0.1 MCPS.  Note that we use the value * 100 so 0.1 equals 10.
   all_ok = vl53l0x_set_signal_rate_limit(10)
   -- Increase laser pulse periods (defaults are 14 and 10 PCLKs).
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18)
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14)
   if !all_ok then
      print_string(serial, "Could not set long range.\r\n")
   end if
end if

if defined(HIGH_SPEED) then
   -- Reduce timing budget to 20 ms (default is about 33 ms).
   if !vl53l0x_set_measurement_timing_budget(20_000) then
      print_string(serial, "Could not set high speed.\r\n")
   end if
elsif defined(HIGH_ACCURACY) then
   -- Increase timing budget to 200 ms.
   if !vl53l0x_set_measurement_timing_budget(200_000) then
      print_string(serial, "Could not set high accuracy.\r\n")
   end if
end if

forever  loop

   ; Start with measurement in mm.
   distance =  vl53l0x_read_range_single_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance =  vl53l0x_read_range_single_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_set_timeout - JALlib Procedures Help

vl53l0x_set_timeout JALLIB PROCEDURE

Signature

procedure vl53l0x_set_timeout(word in timeout) is

Description

Set the response timeout. The response of the VL53L0X depends on the settings
that are used. The timeout given is in ms. Timeout must be > 0 and < 10_000.
Default after initialization is 250 ms.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

  • timeout - word in

Return Value

None

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_set_vcsel_pulse_period - JALlib Procedures Help

vl53l0x_set_vcsel_pulse_period JALLIB FUNCTION

Signature

function vl53l0x_set_vcsel_pulse_period(byte in type, byte in period_pclks) return bit is

Description

Set the VCSEL (vertical cavity surface emitting laser) pulse period for the
given period type (pre-range or final range) to the given value in PCLKs.
Longer periods seem to increase the potential range of the sensor.
Valid values of period_pcklks are (even numbers only):
-) VL53L0X_VCSEL_PERIOD_PRE_RANGE: 12 to 18 (initialized default: 14)
-) VL53L0X_VCSEL_PERIOD_FINAL_RANGE: 8 to 14 (initialized default: 10)
Based on VL53L0X_set_vcsel_pulse_period().
Returns TRUE when succesful.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

  • type - byte in
  • period_pclks - byte in

Return Value

bit - Function return value

Example

From sample file: 16f1825_vl53l0x_single.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using single shot range.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.

-- Settings for the IIC interface used by the MCP23008.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Variables.
var word distance
var bit all_ok

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Use vl53l0x_set_timeout() to increase the timeout value.\r\n")
   print_string(serial, "Or check your IIC connection.\r\n")

end procedure

-- Uncomment this line to use long range mode. This increases the sensitivity
-- of the sensor and extends its potential range, but increases the
-- likelihood of getting an inaccurate reading because of reflections from
-- objects other than the intended target. It works best in dark conditions.
-- const LONG_RANGE = TRUE

-- Uncomment ONE of these two lines to get:
-- -) Higher speed at the cost of lower accuracy OR
-- -) Higher accuracy at the cost of lower speed
-- const HIGH_SPEED = TRUE
-- const HIGH_ACCURACY = TRUE

-- If needed, change IIC address:
-- const NEW_IIC_ADDRESS = TRUE
-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

if defined(LONG_RANGE) then
   -- Lower the return signal rate limit (default is 0.25 MCPS)
   -- to 0.1 MCPS.  Note that we use the value * 100 so 0.1 equals 10.
   all_ok = vl53l0x_set_signal_rate_limit(10)
   -- Increase laser pulse periods (defaults are 14 and 10 PCLKs).
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_PRE_RANGE, 18)
   all_ok = all_ok & vl53l0x_set_vcsel_pulse_period(VL53L0X_VCSEL_PERIOD_FINAL_RANGE, 14)
   if !all_ok then
      print_string(serial, "Could not set long range.\r\n")
   end if
end if

if defined(HIGH_SPEED) then
   -- Reduce timing budget to 20 ms (default is about 33 ms).
   if !vl53l0x_set_measurement_timing_budget(20_000) then
      print_string(serial, "Could not set high speed.\r\n")
   end if
elsif defined(HIGH_ACCURACY) then
   -- Increase timing budget to 200 ms.
   if !vl53l0x_set_measurement_timing_budget(200_000) then
      print_string(serial, "Could not set high accuracy.\r\n")
   end if
end if

forever  loop

   ; Start with measurement in mm.
   distance =  vl53l0x_read_range_single_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance =  vl53l0x_read_range_single_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_start_continuous - JALlib Procedures Help

vl53l0x_start_continuous JALLIB PROCEDURE

Signature

procedure vl53l0x_start_continuous(dword in period_ms) is

Description

Start continuous ranging measurements. If period_ms (optional) is 0 or not
given, continuous back-to-back mode is used (the sensor takes measurements as
often as possible); otherwise, continuous timed mode is used, with the given
inter-measurement period in milliseconds determining how often the sensor
takes a measurement. Based on VL53L0X_StartMeasurement().

Include

To use this procedure, include the library:

include vl53l0x

Parameters

  • period_ms - dword in

Return Value

None

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vl53l0x_timeout_occured - JALlib Procedures Help

vl53l0x_timeout_occured JALLIB FUNCTION

Signature

function vl53l0x_timeout_occured() return bit is

Description

Returns TRUE if a timeout occured in one of the read functions or in case of
timeout on the IIC bus if the IIC timeout is defined. Value is cleared after
a call to this function.

Include

To use this procedure, include the library:

include vl53l0x

Parameters

None

Return Value

bit - Function return value

Example

From sample file: 16f1825_vl53l0x_continuous.jal

-- -----------------------------------------------------------------------------
-- Title: Sample and test program for the VL53L0X Time-of-Flight ranging sensor
-- Author: Rob Jansen, Copyright (c) 2025..2025, all rights reserved.
-- Adapted-by:
-- Compiler: 2.5r9
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: Sample and program showing how to use the VL53L0X Time-of-Flight
--              ranging sensor using continuous mode.
--              This device is controlled via an IIC interface. The serial
--              interface is used to show the result of the measurement.
--              Although the IC does not operate at 5 Volt, the VL53L0X module
--              does operate at 5 Volt and has on-board level shifters including
--              pull-up registers.
--
-- Sources: Based on the vl53l0x-arduino: https://github.com/pololu/vl53l0x-arduino
--          Datasheet STMicroelectronics  VL53L0X DS11555 - Rev 6
--

include 16f1825

-- This program uses the internal oscillator at 32 MHz.
pragma target clock    32_000_000      -- oscillator frequency
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PLLEN    ENABLED         -- PLL on to get 32 MHz
pragma target WDT      DISABLED        -- No Watchdog
pragma target PWRTE    ENABLED         -- Power up timer enabled
pragma target BROWNOUT DISABLED        -- No brownout reset
pragma target FCMEN    DISABLED        -- No clock monitoring
pragma target IESO     DISABLED        -- int/ext osc. switch
pragma target LVP      ENABLED         -- Low voltage programming
pragma target MCLR     EXTERNAL        -- Reset external
-- Set the internal clock frequency to 32 MHz.
OSCCON_IRCF   = 0b1110                 -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00                   -- Clock determined by FOSC (32 MHz)

; Enable weak pull up for all unused pins.
WPUA = 0b0011_1111
WPUC = 0b0010_1100
OPTION_REG_WPUEN = FALSE -- Enable Weak Pull-Up

enable_digital_io()
_usec_delay(100_000)

; Setup uart for communication.
alias pin_RX_direction is pin_RX_RC5_direction -- Pin 5 of 14 pin DIP.
alias pin_TX_direction is pin_TX_RC4_direction -- Pin 6 of 14 pin DIP.
const serial_hw_baudrate  = 115200
include serial_hardware
serial_hw_init()
alias serial is serial_hw_data

include print
include delay

-- Define the IIC pins and initiaize the pin direction.
alias i2c_scl is pin_C0 -- Pin 10 for 14 pin DIP
-- alias pin_scl_direction is pin_C0_direction. Note: Not needed for this PIC.
alias i2c_sda is pin_C1 -- Pin 9 for 14 pin DIP.
-- alias pin_sda_direction is pin_C1_direction. Note: Not needed for this PIC.
const word _i2c_bus_speed = 1 -- 100 kHz. It can handle 400 kHz.
const bit  _i2c_level = TRUE  -- i2c levels (not SMB)
const word I2C_HARDWARE_TIMEOUT = 10_000 -- At least 10 ms to prevent hang-up.
include i2c_hardware
i2c_initialize()
-- Now include the library.
include vl53l0x

-- Procedures.
procedure print_iic_address() is

   print_string(serial, "VL53L0X module IIC address is: 0x")
   print_byte_hex(serial, vl53l0x_get_iic_address())
   print_crlf(serial)

end procedure

; Print the timeout value.
procedure print_timeout() is

   print_string(serial, "Timeout occured.\r\n")
   print_string(serial, "Retry with at timeout value of: ")
   print_word_dec(serial, vl53l0x_get_timeout())
   print_string(serial, " ms.\r\n")

end procedure

-- Variables.
var word distance

-- If needed, change IIC address:
--- const NEW_IIC_ADDRESS = TRUE

-- ------------------------------ Main program ---------------------------------

print_crlf(serial)
print_string(serial, "Test program for the VL53L0X Time-of-Flight ranging sensor.\r\n")

if defined(NEW_IIC_ADDRESS) then
   -- Set the IIC address to a different address than the default
   -- address VL53L0X_IIC_DEFAULT_ADDRESS.
   print_iic_address()
   -- Change address.
   vl53l0x_set_iic_address(0x54)
   -- Show the current IIC address.
   print_iic_address()
end if

-- Initialize the VL53L0X library.
print_string(serial, "Initializing ...\r\n")
while !vl53l0x_init() loop
   serial = "."
   _usec_delay(250_000)
end loop
print_string(serial, "Done!\r\n")

-- Use continuous mode and sample every 100 ms. Note that when a large value is
-- used, it may be needed to increase the default timeout value.
vl53l0x_start_continuous(100)

forever loop

   ; Start with measurement in mm.
   distance = vl53l0x_read_range_continuous_millimeters()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range is in mm: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if

   ; Now in mil.
   distance = vl53l0x_read_range_continuous_mil()
   if vl53l0x_timeout_occured() then
      print_timeout()
      ; Make it a bit bigger.
      vl53l0x_set_timeout(vl53l0x_get_timeout() + 10)
   else
      print_string(serial, "Range in mil: ")
      print_word_dec(serial, distance)
      print_crlf(serial)
   end if
   print_crlf(serial)

end loop

Generated by JALlib CHM Help System | Source: vl53l0x.jal


vs_file_info - JALlib Procedures Help

vs_file_info JALLIB PROCEDURE

Signature

procedure vs_file_info() is

Description

Get info about music that is currently playing. So far only gets file type
(MP3, WAV, AAC, WMA, MIDI, OGG)

Include

To use this procedure, include the library:

include mp3_decoder_vs1053b

Parameters

None

Return Value

None

Example

From sample file: 18f4620_mp3_decoder_vs1053b_pata_hard_disk.jal

-- Title: MP3 decoder vs1053b sample
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example usage of the vs1053 mp3 decoder. plays .mp3 files from
--              a fat32 formatted sd card or hard disk. Full control of play
--              speed, volume, right/left speaker, bass, treble, mute.
--              Also plays Ogg Vorbis/AAC/WMA/MIDI
--
-- Notes:
-- vs1053 uses SPI mode 0,0
-- must use 12.288mhz crystal for vs1053b
--
-- Sources:
-- VLSI Solutions Datasheet - www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include strings

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- setup vs1053(b)
const byte str3[] = "INITIALIZING VS1053B"
print_string(serial_hw_data, str3)
--
alias vs_command_chip_select              is pin_e1                     -- command chip select pin
alias vs_command_chip_select_direction    is pin_e1_direction
alias vs_data_chip_select                 is pin_e2                     -- data chip select pin
alias vs_data_chip_select_direction       is pin_e2_direction
alias vs_dreq                             is pin_c0                     -- data request pin
alias vs_dreq_direction                   is pin_c0
--
vs_command_chip_select_direction = output
vs_data_chip_select_direction = output
vs_dreq_direction = input
--
vs_command_chip_select = high -- disable command chip select
vs_data_chip_select = high -- disable data chip select
--
-- select weather or not to switch SPI modes before every read/write
-- needed if using more then one component on the SPI bus.
-- enabled when vs_force_spi_mode is defined.
alias vs_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
--
-- 5x pll (interal clock runs at 12.288mhz * 5 = 61.44)
-- note: higher SPI speeds require high PLL
const byte VS_PLL = 5 -- choose 1, 3_5 (3.5), or 5
const byte VS_SPI_COMMAND_SPEED = SPI_RATE_FOSC_64 -- choose speed to send commands
--
include mp3_decoder_vs1053b
vs_init()

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- start of main program
vs_volume = 240 -- set startup volume

-- example of using an output pin
var bit my_pin_name is vs_pin_gpio0
var bit my_pin_name_direction is vs_pin_gpio0_direction
my_pin_name_direction = output
my_pin_name = high

-- some vars
var sword db_level  -- will hold volume db (decibel) level

seperator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

------------------------------------------------------------
-- example user interaction,
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into a mp3 file and play it
------------------------------------------------------------

var byte file_number = 0
var dword count8 = 0

forever loop
   seperator() -- send "-----"

   -- wait for user to send serial data (file selection)
   while !serial_hw_data_available loop
   end loop

   file_number = serial_hw_data

   if !(file_number > fat32_dir_file_count) then -- if the file number exists
      -- display the file_name chosen
      print_word_dec(serial_hw_data,file_number)
      const byte string1[] = {0x2E,0x20,0x20} -- ".  "
      print_string(serial_hw_data,string1)
      fat32_read_file_info(file_number) -- read file's name, location, size, attributes into memory
      fat32_print_file_info(serial_hw_data,FAT32_PRINT_ALL)
      seperator() -- send "-----"
   end if

   -- do something with the chosen file number
   if fat32_cd(file_number) then            -- if change directory is successful
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL)                      -- sends dir listing via serial port

   elsif fat32_file_open(file_number) then  -- if file open is successful
      var dword sector_step = 0
      count8 = 0

      vs_play() -- allow vs1053b to play music

      -- continue till no data is left.
      for (fat32_file_size / 512) + 1 loop
         fat32_read_file_sector_number(sector_step)
         sector_step = sector_step + 1

         -- do something with the data
         if string_compare(fat32_file_extension, "mp3") then

            -- now send it to vs1053b

            -- set to spi mode 00
            spi_master_hw_set_mode_00()

            -- enable vs1053b
            vs_data_chip_select = low

            var word count1                        -- sector data count
            count1 = 0
            for 16 loop                             -- loop till end of sector read

               -- wait till data gets requested
               while vs_dreq == low loop
               end loop

               -- vs1053b can take up to 32 bytes when vs_dreq is low
               for 32 loop
                  spi_master_hw = fat32_sector_buffer[count1]
                  count1 = count1 + 1
               end loop
            end loop
         else
            var word count1 = 0
            for 512 loop
               serial_hw_data = fat32_sector_buffer[count1]
               count1 = count1 + 1
            end loop
         end if

         -- get users input via serial port to control music (volume, play speed, stop, etc.)
         if serial_hw_data_available == TRUE then
            var byte serial_data = serial_hw_data
            if serial_data == 0 then                    -- stop
               fat32_set_idle()          -- set data device to idle state
               vs_stop()                 -- stop the audio
               vs_data_chip_select = low -- disable mp3 decoder
               exit loop
            elsif serial_data == 50 then                -- volume down
               if vs_volume != 0 then
                  vs_volume = vs_volume - 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 51 then                -- volume up
               if vs_volume != 255 then
                  vs_volume = vs_volume + 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 52 then                -- volume down right only
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 53 then                -- volume up right only
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 54 then                -- volume down left only
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 55 then                -- volume up left only
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 56 then                -- move volume right to left
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 57 then                -- move volume left to right
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 58 then                -- slower play speed
               if !(vs_play_speed == 1) then
                  vs_play_speed = vs_play_speed - 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 59 then                -- faster play speed (fast-forward)
               if !(vs_play_speed == 10) then
                  vs_play_speed = vs_play_speed + 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 60 then                -- get file info, so far
               vs_file_info()                           -- only file type " MP3", "MIDI", etc.
               print_string(serial_hw_data,vs_current_file_type) -- send filetype
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_bitrate)       -- send bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_average_bitrate) -- send avgerage bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_samplerate)  -- send samplerate
               print_crlf(serial_hw_data)
            elsif serial_data == 61 then                -- MUTE
               vs_mute = TRUE
               print_byte_dec(serial_hw_data, 1)
            elsif serial_data == 62 then                -- NO MUTE
               vs_mute = FALSE
               print_byte_dec(serial_hw_data, vs_mute)
            elsif serial_data == 63 then                -- bass down
               if vs_bass != 0 then
                  vs_bass = vs_bass - 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 64 then                -- bass up
               if vs_bass != 15 then
                  vs_bass = vs_bass + 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 65 then                -- treble down
               if vs_treble != -8 then
                  vs_treble = vs_treble - 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            elsif serial_data == 66 then                -- treble up
               if vs_treble != 7 then
                  vs_treble = vs_treble + 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            end if

            -- send return char
            serial_hw_data = 13
            serial_hw_data = 10
         end if
         vs_data_chip_select = high -- disable vs1053b
         count8 = count8 + 1

      end loop
      -- close the file
      fat32_file_close()
      seperator()
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   end if
end loop

Generated by JALlib CHM Help System | Source: mp3_decoder_vs1053b.jal


vs_init - JALlib Procedures Help

vs_init JALLIB PROCEDURE

Signature

procedure vs_init() is

Description

Initialize vs1053b and set volume to max. User should lower volume after
init(). After init() vs_reg_mode_data should be equal to 0x4800 or 0x800

Include

To use this procedure, include the library:

include mp3_decoder_vs1053b

Parameters

None

Return Value

None

Example

From sample file: 18f4620_mp3_decoder_vs1053b_pata_hard_disk.jal

-- Title: MP3 decoder vs1053b sample
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example usage of the vs1053 mp3 decoder. plays .mp3 files from
--              a fat32 formatted sd card or hard disk. Full control of play
--              speed, volume, right/left speaker, bass, treble, mute.
--              Also plays Ogg Vorbis/AAC/WMA/MIDI
--
-- Notes:
-- vs1053 uses SPI mode 0,0
-- must use 12.288mhz crystal for vs1053b
--
-- Sources:
-- VLSI Solutions Datasheet - www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include strings

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- setup vs1053(b)
const byte str3[] = "INITIALIZING VS1053B"
print_string(serial_hw_data, str3)
--
alias vs_command_chip_select              is pin_e1                     -- command chip select pin
alias vs_command_chip_select_direction    is pin_e1_direction
alias vs_data_chip_select                 is pin_e2                     -- data chip select pin
alias vs_data_chip_select_direction       is pin_e2_direction
alias vs_dreq                             is pin_c0                     -- data request pin
alias vs_dreq_direction                   is pin_c0
--
vs_command_chip_select_direction = output
vs_data_chip_select_direction = output
vs_dreq_direction = input
--
vs_command_chip_select = high -- disable command chip select
vs_data_chip_select = high -- disable data chip select
--
-- select weather or not to switch SPI modes before every read/write
-- needed if using more then one component on the SPI bus.
-- enabled when vs_force_spi_mode is defined.
alias vs_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
--
-- 5x pll (interal clock runs at 12.288mhz * 5 = 61.44)
-- note: higher SPI speeds require high PLL
const byte VS_PLL = 5 -- choose 1, 3_5 (3.5), or 5
const byte VS_SPI_COMMAND_SPEED = SPI_RATE_FOSC_64 -- choose speed to send commands
--
include mp3_decoder_vs1053b
vs_init()

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- start of main program
vs_volume = 240 -- set startup volume

-- example of using an output pin
var bit my_pin_name is vs_pin_gpio0
var bit my_pin_name_direction is vs_pin_gpio0_direction
my_pin_name_direction = output
my_pin_name = high

-- some vars
var sword db_level  -- will hold volume db (decibel) level

seperator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

------------------------------------------------------------
-- example user interaction,
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into a mp3 file and play it
------------------------------------------------------------

var byte file_number = 0
var dword count8 = 0

forever loop
   seperator() -- send "-----"

   -- wait for user to send serial data (file selection)
   while !serial_hw_data_available loop
   end loop

   file_number = serial_hw_data

   if !(file_number > fat32_dir_file_count) then -- if the file number exists
      -- display the file_name chosen
      print_word_dec(serial_hw_data,file_number)
      const byte string1[] = {0x2E,0x20,0x20} -- ".  "
      print_string(serial_hw_data,string1)
      fat32_read_file_info(file_number) -- read file's name, location, size, attributes into memory
      fat32_print_file_info(serial_hw_data,FAT32_PRINT_ALL)
      seperator() -- send "-----"
   end if

   -- do something with the chosen file number
   if fat32_cd(file_number) then            -- if change directory is successful
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL)                      -- sends dir listing via serial port

   elsif fat32_file_open(file_number) then  -- if file open is successful
      var dword sector_step = 0
      count8 = 0

      vs_play() -- allow vs1053b to play music

      -- continue till no data is left.
      for (fat32_file_size / 512) + 1 loop
         fat32_read_file_sector_number(sector_step)
         sector_step = sector_step + 1

         -- do something with the data
         if string_compare(fat32_file_extension, "mp3") then

            -- now send it to vs1053b

            -- set to spi mode 00
            spi_master_hw_set_mode_00()

            -- enable vs1053b
            vs_data_chip_select = low

            var word count1                        -- sector data count
            count1 = 0
            for 16 loop                             -- loop till end of sector read

               -- wait till data gets requested
               while vs_dreq == low loop
               end loop

               -- vs1053b can take up to 32 bytes when vs_dreq is low
               for 32 loop
                  spi_master_hw = fat32_sector_buffer[count1]
                  count1 = count1 + 1
               end loop
            end loop
         else
            var word count1 = 0
            for 512 loop
               serial_hw_data = fat32_sector_buffer[count1]
               count1 = count1 + 1
            end loop
         end if

         -- get users input via serial port to control music (volume, play speed, stop, etc.)
         if serial_hw_data_available == TRUE then
            var byte serial_data = serial_hw_data
            if serial_data == 0 then                    -- stop
               fat32_set_idle()          -- set data device to idle state
               vs_stop()                 -- stop the audio
               vs_data_chip_select = low -- disable mp3 decoder
               exit loop
            elsif serial_data == 50 then                -- volume down
               if vs_volume != 0 then
                  vs_volume = vs_volume - 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 51 then                -- volume up
               if vs_volume != 255 then
                  vs_volume = vs_volume + 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 52 then                -- volume down right only
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 53 then                -- volume up right only
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 54 then                -- volume down left only
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 55 then                -- volume up left only
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 56 then                -- move volume right to left
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 57 then                -- move volume left to right
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 58 then                -- slower play speed
               if !(vs_play_speed == 1) then
                  vs_play_speed = vs_play_speed - 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 59 then                -- faster play speed (fast-forward)
               if !(vs_play_speed == 10) then
                  vs_play_speed = vs_play_speed + 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 60 then                -- get file info, so far
               vs_file_info()                           -- only file type " MP3", "MIDI", etc.
               print_string(serial_hw_data,vs_current_file_type) -- send filetype
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_bitrate)       -- send bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_average_bitrate) -- send avgerage bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_samplerate)  -- send samplerate
               print_crlf(serial_hw_data)
            elsif serial_data == 61 then                -- MUTE
               vs_mute = TRUE
               print_byte_dec(serial_hw_data, 1)
            elsif serial_data == 62 then                -- NO MUTE
               vs_mute = FALSE
               print_byte_dec(serial_hw_data, vs_mute)
            elsif serial_data == 63 then                -- bass down
               if vs_bass != 0 then
                  vs_bass = vs_bass - 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 64 then                -- bass up
               if vs_bass != 15 then
                  vs_bass = vs_bass + 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 65 then                -- treble down
               if vs_treble != -8 then
                  vs_treble = vs_treble - 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            elsif serial_data == 66 then                -- treble up
               if vs_treble != 7 then
                  vs_treble = vs_treble + 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            end if

            -- send return char
            serial_hw_data = 13
            serial_hw_data = 10
         end if
         vs_data_chip_select = high -- disable vs1053b
         count8 = count8 + 1

      end loop
      -- close the file
      fat32_file_close()
      seperator()
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   end if
end loop

Generated by JALlib CHM Help System | Source: mp3_decoder_vs1053b.jal


vs_play - JALlib Procedures Help

vs_play JALLIB PROCEDURE

Signature

procedure vs_play() is

Description

Clear vs1053 registers before playing a file

Include

To use this procedure, include the library:

include mp3_decoder_vs1053b

Parameters

None

Return Value

None

Example

From sample file: 18f4620_mp3_decoder_vs1053b_pata_hard_disk.jal

-- Title: MP3 decoder vs1053b sample
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example usage of the vs1053 mp3 decoder. plays .mp3 files from
--              a fat32 formatted sd card or hard disk. Full control of play
--              speed, volume, right/left speaker, bass, treble, mute.
--              Also plays Ogg Vorbis/AAC/WMA/MIDI
--
-- Notes:
-- vs1053 uses SPI mode 0,0
-- must use 12.288mhz crystal for vs1053b
--
-- Sources:
-- VLSI Solutions Datasheet - www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include strings

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- setup vs1053(b)
const byte str3[] = "INITIALIZING VS1053B"
print_string(serial_hw_data, str3)
--
alias vs_command_chip_select              is pin_e1                     -- command chip select pin
alias vs_command_chip_select_direction    is pin_e1_direction
alias vs_data_chip_select                 is pin_e2                     -- data chip select pin
alias vs_data_chip_select_direction       is pin_e2_direction
alias vs_dreq                             is pin_c0                     -- data request pin
alias vs_dreq_direction                   is pin_c0
--
vs_command_chip_select_direction = output
vs_data_chip_select_direction = output
vs_dreq_direction = input
--
vs_command_chip_select = high -- disable command chip select
vs_data_chip_select = high -- disable data chip select
--
-- select weather or not to switch SPI modes before every read/write
-- needed if using more then one component on the SPI bus.
-- enabled when vs_force_spi_mode is defined.
alias vs_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
--
-- 5x pll (interal clock runs at 12.288mhz * 5 = 61.44)
-- note: higher SPI speeds require high PLL
const byte VS_PLL = 5 -- choose 1, 3_5 (3.5), or 5
const byte VS_SPI_COMMAND_SPEED = SPI_RATE_FOSC_64 -- choose speed to send commands
--
include mp3_decoder_vs1053b
vs_init()

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- start of main program
vs_volume = 240 -- set startup volume

-- example of using an output pin
var bit my_pin_name is vs_pin_gpio0
var bit my_pin_name_direction is vs_pin_gpio0_direction
my_pin_name_direction = output
my_pin_name = high

-- some vars
var sword db_level  -- will hold volume db (decibel) level

seperator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

------------------------------------------------------------
-- example user interaction,
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into a mp3 file and play it
------------------------------------------------------------

var byte file_number = 0
var dword count8 = 0

forever loop
   seperator() -- send "-----"

   -- wait for user to send serial data (file selection)
   while !serial_hw_data_available loop
   end loop

   file_number = serial_hw_data

   if !(file_number > fat32_dir_file_count) then -- if the file number exists
      -- display the file_name chosen
      print_word_dec(serial_hw_data,file_number)
      const byte string1[] = {0x2E,0x20,0x20} -- ".  "
      print_string(serial_hw_data,string1)
      fat32_read_file_info(file_number) -- read file's name, location, size, attributes into memory
      fat32_print_file_info(serial_hw_data,FAT32_PRINT_ALL)
      seperator() -- send "-----"
   end if

   -- do something with the chosen file number
   if fat32_cd(file_number) then            -- if change directory is successful
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL)                      -- sends dir listing via serial port

   elsif fat32_file_open(file_number) then  -- if file open is successful
      var dword sector_step = 0
      count8 = 0

      vs_play() -- allow vs1053b to play music

      -- continue till no data is left.
      for (fat32_file_size / 512) + 1 loop
         fat32_read_file_sector_number(sector_step)
         sector_step = sector_step + 1

         -- do something with the data
         if string_compare(fat32_file_extension, "mp3") then

            -- now send it to vs1053b

            -- set to spi mode 00
            spi_master_hw_set_mode_00()

            -- enable vs1053b
            vs_data_chip_select = low

            var word count1                        -- sector data count
            count1 = 0
            for 16 loop                             -- loop till end of sector read

               -- wait till data gets requested
               while vs_dreq == low loop
               end loop

               -- vs1053b can take up to 32 bytes when vs_dreq is low
               for 32 loop
                  spi_master_hw = fat32_sector_buffer[count1]
                  count1 = count1 + 1
               end loop
            end loop
         else
            var word count1 = 0
            for 512 loop
               serial_hw_data = fat32_sector_buffer[count1]
               count1 = count1 + 1
            end loop
         end if

         -- get users input via serial port to control music (volume, play speed, stop, etc.)
         if serial_hw_data_available == TRUE then
            var byte serial_data = serial_hw_data
            if serial_data == 0 then                    -- stop
               fat32_set_idle()          -- set data device to idle state
               vs_stop()                 -- stop the audio
               vs_data_chip_select = low -- disable mp3 decoder
               exit loop
            elsif serial_data == 50 then                -- volume down
               if vs_volume != 0 then
                  vs_volume = vs_volume - 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 51 then                -- volume up
               if vs_volume != 255 then
                  vs_volume = vs_volume + 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 52 then                -- volume down right only
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 53 then                -- volume up right only
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 54 then                -- volume down left only
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 55 then                -- volume up left only
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 56 then                -- move volume right to left
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 57 then                -- move volume left to right
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 58 then                -- slower play speed
               if !(vs_play_speed == 1) then
                  vs_play_speed = vs_play_speed - 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 59 then                -- faster play speed (fast-forward)
               if !(vs_play_speed == 10) then
                  vs_play_speed = vs_play_speed + 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 60 then                -- get file info, so far
               vs_file_info()                           -- only file type " MP3", "MIDI", etc.
               print_string(serial_hw_data,vs_current_file_type) -- send filetype
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_bitrate)       -- send bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_average_bitrate) -- send avgerage bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_samplerate)  -- send samplerate
               print_crlf(serial_hw_data)
            elsif serial_data == 61 then                -- MUTE
               vs_mute = TRUE
               print_byte_dec(serial_hw_data, 1)
            elsif serial_data == 62 then                -- NO MUTE
               vs_mute = FALSE
               print_byte_dec(serial_hw_data, vs_mute)
            elsif serial_data == 63 then                -- bass down
               if vs_bass != 0 then
                  vs_bass = vs_bass - 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 64 then                -- bass up
               if vs_bass != 15 then
                  vs_bass = vs_bass + 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 65 then                -- treble down
               if vs_treble != -8 then
                  vs_treble = vs_treble - 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            elsif serial_data == 66 then                -- treble up
               if vs_treble != 7 then
                  vs_treble = vs_treble + 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            end if

            -- send return char
            serial_hw_data = 13
            serial_hw_data = 10
         end if
         vs_data_chip_select = high -- disable vs1053b
         count8 = count8 + 1

      end loop
      -- close the file
      fat32_file_close()
      seperator()
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   end if
end loop

Generated by JALlib CHM Help System | Source: mp3_decoder_vs1053b.jal


vs_stop - JALlib Procedures Help

vs_stop JALLIB PROCEDURE

Signature

procedure vs_stop() is

Description

clears vs_1053b data input buffer. This should be done after
sending mp3 data, otherwise you will get some unwanted sound from the
previous file played.

Include

To use this procedure, include the library:

include mp3_decoder_vs1053b

Parameters

None

Return Value

None

Example

From sample file: 18f4620_mp3_decoder_vs1053b_pata_hard_disk.jal

-- Title: MP3 decoder vs1053b sample
-- Author: Matthew Schinkel, copyright (c) 2009, all rights reserved.
-- Adapted-by:
-- Compiler: >=2.4q3
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: example usage of the vs1053 mp3 decoder. plays .mp3 files from
--              a fat32 formatted sd card or hard disk. Full control of play
--              speed, volume, right/left speaker, bass, treble, mute.
--              Also plays Ogg Vorbis/AAC/WMA/MIDI
--
-- Notes:
-- vs1053 uses SPI mode 0,0
-- must use 12.288mhz crystal for vs1053b
--
-- Sources:
-- VLSI Solutions Datasheet - www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf
--
-- This file has been generated by Matt's sample generator.
--

include 18f4620                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
pragma target clock 40_000_000      -- oscillator frequency
--
pragma target OSC      HS_PLL                    -- crystal or resonator
pragma target WDT      CONTROL                   -- watchdog
pragma target XINST    DISABLED                  -- extended instruction set
pragma target DEBUG    DISABLED                  -- debugging
pragma target BROWNOUT DISABLED                  -- brownout reset
pragma target FCMEN    DISABLED                  -- clock monitoring
pragma target IESO     DISABLED                  -- int/ext osc. switch
pragma target LVP      ENABLED                   -- low voltage programming
pragma target MCLR     EXTERNAL                  -- reset
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program. Other programs may need more or different settings.
--
WDTCON_SWDTEN = OFF                 -- disable WDT
OSCCON_SCS = 0                      -- select primary oscillator
OSCTUNE_PLLEN = TRUE                -- PLL
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000)               -- wait for power to stablilize

include delay

const PRINT_MAX_VAR_SIZE = 6
include print

-- setup uart for communication
const serial_hw_baudrate  = 115200   -- set the baudrate
include serial_hardware
serial_hw_init()
-- some aliases so it is easy to change from serial hw to serial sw.
alias serial_write is serial_hw_write
alias serial_read is serial_hw_read
alias serial_data is serial_hw_data
alias serial_data_available is serial_hw_data_available
--
var byte sample_started[] = "***Jallib Sample Started***"
print_string(serial_data,sample_started)
print_crlf(serial_data)

include strings

-- setup SPI library
include spi_master_hw         -- includes the spi library
-- define spi inputs/outputs
pin_sdi_direction = input    -- spi input
pin_sdo_direction = output   -- spi output
pin_sck_direction = output   -- spi clock
--
spi_init(SPI_MODE_11,SPI_RATE_FOSC_4) -- init spi, choose mode and speed
alias spi_master is spi_master_hw
alias spi_master_exchange is spi_master_hw_exchange

-- setup 23k256 for external memory
-- setup chip select pin
ALIAS sram_23k256_chip_select             is pin_a1
ALIAS sram_23k256_chip_select_direction   is pin_a1_direction
-- initial settings
sram_23k256_chip_select_direction = output    -- chip select/slave select pin
sram_23k256_chip_select = high                -- start chip slect high (chip disabled)
-- initalize 23k256 in byte mode
alias sram_23k256_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
include sram_23k256 -- setup Microchip 23k256 sram
sram_23k256_init(SRAM_23K256_SEQUENTIAL_MODE, SRAM_23K256_HOLD_DISABLE)  -- init 23k256 in sequential mode

-- setup hard disk library
const bit PATA_HD_READ_EXTRA_SPEED = FALSE -- uses additonal code space to add a speed boost to sector_read procedures
CONST BYTE PATA_HD_USE_CS0_CS1_PINS = FALSE -- set true if you will use Alternate Status, Digital Output or Drive Address registers
const bit PATA_HD_NO_INVERTER = TRUE -- if true, an external inverter chip is not needed on /iowr, /iord, /cs0, /cs1 pins
-- pin assignments
alias     pata_hd_data_low              is portb   -- data port (low bits)
alias     pata_hd_data_low_direction    is portb_direction
alias     pata_hd_data_high             is portd   -- data port (high bits)
alias     pata_hd_data_high_direction   is portd_direction
alias     pata_hd_a0                    is pin_a3
alias     pata_hd_a0_direction          is pin_a3_direction
alias     pata_hd_a1                    is pin_a1
alias     pata_hd_a1_direction          is pin_a1_direction
alias     pata_hd_a2                    is pin_a0
alias     pata_hd_a2_direction          is pin_a0_direction
alias     pata_hd_iowr                  is pin_e0
alias     pata_hd_iowr_direction        is pin_e0_direction
alias     pata_hd_iord                  is pin_a4
alias     pata_hd_iord_direction        is pin_a4_direction
;alias     pata_hd_cs1                   is pin_a3
;alias     pata_hd_cs1_direction         is pin_a3_direction
;alias     pata_hd_cs0                   is pin_a4
;alias     pata_hd_cs0_direction         is pin_a4_direction

pata_hd_a0_direction = output    -- register select pin
pata_hd_a1_direction = output    -- register select pin
pata_hd_a2_direction = output    -- register select pin
pata_hd_iowr_direction = output  -- used for write pulse
pata_hd_iord_direction = output  -- used for read pulse
;pata_hd_cs1_direction = output   -- register select pin
;pata_hd_cs0_direction = output   -- register select pin
--
include pata_hard_disk           -- include the parallel ata ide hard disk library
pata_hd_init()                   -- initialize startup settings

-- setup fat32 --
-- include the required files
;include pic_data_eeprom
-- change these vaues to save memory
const bit FAT32_WRITE_LONG_FILE_NAMES = FALSE -- support writing of long file names
const word FAT32_FILES_MAX = 20            -- the max number of files allowed in a directory
const byte FAT32_FILE_NAME_SIZE = 80        -- choose max file_name size. if a file_name is longer the this, beginning chars will be cut. short file_names are 12 bytes.
const FAT32_DIR_FRAGMENTS_TO_ALLOW = 5     -- uses 6 bytes memory per fragment allowed (0 not allowed)
--                                          -- windows defrag does not defragment directories.
const FAT32_FILE_FRAGMENTS_TO_ALLOW = 5    -- uses 8 bytes memory per fragment allowed (0 not allowed)
--
-- experts may change the following values
;const byte FAT32_ENTRIES_MAX = 1           -- highest file entry address can be 256
const byte FAT32_ENTRIES_MAX = 2            -- highest file entry address can be 65535
--
-- choose a memory source for the file list
const bit FAT32_USE_INTERNAL_MEMORY = TRUE -- Use internal memory for file location list
IF FAT32_USE_INTERNAL_MEMORY == TRUE THEN
   -- Setup a large array for storing sector data, This is where file_name locations are stored
   const dword LARGE_ARRAY_2_SIZE = FAT32_FILES_MAX               -- choose number of array variables
   const dword LARGE_ARRAY_2_VARIABLE_SIZE = FAT32_ENTRIES_MAX    -- choose bytes size of variables
   include large_array_2                    -- include the array library
   ALIAS fat32_entry_location is large_array_2
elsif FAT32_USE_INTERNAL_MEMORY == FALSE THEN
   -- put your own code here if you wish to allow massive amounts of files per directory

   -- example usage of 23k256 for external memory

   -- alias the 23k256 device word array
   ;alias entry_location is sram_23k256_byte  -- highest file entry address can be 256
   alias fat32_entry_location is sram_23k256_word   -- highest file entry address can be 65535
END IF
--
include fat32   -- include fat32 library -- include fat32

-- CHOOSE FILE ATTRIBUTES TO FILTER OUT
fat32_filter_is_read_only  = FALSE
fat32_filter_is_hidden     = FALSE
fat32_filter_is_system     = FALSE
fat32_filter_is_volume_id  = FALSE
fat32_filter_is_directory  = FALSE
fat32_filter_is_archive    = FALSE

-- setup vs1053(b)
const byte str3[] = "INITIALIZING VS1053B"
print_string(serial_hw_data, str3)
--
alias vs_command_chip_select              is pin_e1                     -- command chip select pin
alias vs_command_chip_select_direction    is pin_e1_direction
alias vs_data_chip_select                 is pin_e2                     -- data chip select pin
alias vs_data_chip_select_direction       is pin_e2_direction
alias vs_dreq                             is pin_c0                     -- data request pin
alias vs_dreq_direction                   is pin_c0
--
vs_command_chip_select_direction = output
vs_data_chip_select_direction = output
vs_dreq_direction = input
--
vs_command_chip_select = high -- disable command chip select
vs_data_chip_select = high -- disable data chip select
--
-- select weather or not to switch SPI modes before every read/write
-- needed if using more then one component on the SPI bus.
-- enabled when vs_force_spi_mode is defined.
alias vs_force_spi_mode is spi_master_hw_set_mode_00 -- always set spi mode to 0,0
--
-- 5x pll (interal clock runs at 12.288mhz * 5 = 61.44)
-- note: higher SPI speeds require high PLL
const byte VS_PLL = 5 -- choose 1, 3_5 (3.5), or 5
const byte VS_SPI_COMMAND_SPEED = SPI_RATE_FOSC_64 -- choose speed to send commands
--
include mp3_decoder_vs1053b
vs_init()

-- procedure for sending 80 "-----------------" via serial port
procedure seperator() is
   serial_hw_data = 13
   serial_hw_data = 10
   const byte str3[] = "--------------------------------------------------------------------------------"
   print_string(serial_hw_data, str3)
   print_crlf(serial_hw_data)
end procedure

-- start of main program
vs_volume = 240 -- set startup volume

-- example of using an output pin
var bit my_pin_name is vs_pin_gpio0
var bit my_pin_name_direction is vs_pin_gpio0_direction
my_pin_name_direction = output
my_pin_name = high

-- some vars
var sword db_level  -- will hold volume db (decibel) level

seperator()-- send "----"

fat32_init(1) -- initialize fat32, go to 1st primary partition's root dir "\"

------------------------------------------------------------
-- list a directory, send it via serial port
------------------------------------------------------------
fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port

------------------------------------------------------------
-- example user interaction,
-- if volume id selected, list the current dir (root dir)
-- if directory selected go into it and list it
-- if file selected go into a mp3 file and play it
------------------------------------------------------------

var byte file_number = 0
var dword count8 = 0

forever loop
   seperator() -- send "-----"

   -- wait for user to send serial data (file selection)
   while !serial_hw_data_available loop
   end loop

   file_number = serial_hw_data

   if !(file_number > fat32_dir_file_count) then -- if the file number exists
      -- display the file_name chosen
      print_word_dec(serial_hw_data,file_number)
      const byte string1[] = {0x2E,0x20,0x20} -- ".  "
      print_string(serial_hw_data,string1)
      fat32_read_file_info(file_number) -- read file's name, location, size, attributes into memory
      fat32_print_file_info(serial_hw_data,FAT32_PRINT_ALL)
      seperator() -- send "-----"
   end if

   -- do something with the chosen file number
   if fat32_cd(file_number) then            -- if change directory is successful
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL)                      -- sends dir listing via serial port

   elsif fat32_file_open(file_number) then  -- if file open is successful
      var dword sector_step = 0
      count8 = 0

      vs_play() -- allow vs1053b to play music

      -- continue till no data is left.
      for (fat32_file_size / 512) + 1 loop
         fat32_read_file_sector_number(sector_step)
         sector_step = sector_step + 1

         -- do something with the data
         if string_compare(fat32_file_extension, "mp3") then

            -- now send it to vs1053b

            -- set to spi mode 00
            spi_master_hw_set_mode_00()

            -- enable vs1053b
            vs_data_chip_select = low

            var word count1                        -- sector data count
            count1 = 0
            for 16 loop                             -- loop till end of sector read

               -- wait till data gets requested
               while vs_dreq == low loop
               end loop

               -- vs1053b can take up to 32 bytes when vs_dreq is low
               for 32 loop
                  spi_master_hw = fat32_sector_buffer[count1]
                  count1 = count1 + 1
               end loop
            end loop
         else
            var word count1 = 0
            for 512 loop
               serial_hw_data = fat32_sector_buffer[count1]
               count1 = count1 + 1
            end loop
         end if

         -- get users input via serial port to control music (volume, play speed, stop, etc.)
         if serial_hw_data_available == TRUE then
            var byte serial_data = serial_hw_data
            if serial_data == 0 then                    -- stop
               fat32_set_idle()          -- set data device to idle state
               vs_stop()                 -- stop the audio
               vs_data_chip_select = low -- disable mp3 decoder
               exit loop
            elsif serial_data == 50 then                -- volume down
               if vs_volume != 0 then
                  vs_volume = vs_volume - 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 51 then                -- volume up
               if vs_volume != 255 then
                  vs_volume = vs_volume + 1
               end if
               print_byte_dec(serial_hw_data, vs_volume)
               -- invert to negitive word value for volume in db (decibels)
               db_level = sword(255 - vs_volume)
               db_level = !(db_level * 5) + 1
               -- send volume to serial port
               format_sword_dec(serial_hw_data, db_level,6,1)
               serial_hw_data = "d"
               serial_hw_data = "b"
            elsif serial_data == 52 then                -- volume down right only
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 53 then                -- volume up right only
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 54 then                -- volume down left only
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 55 then                -- volume up left only
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
            elsif serial_data == 56 then                -- move volume right to left
               if vs_volume_left != 127 then
                  vs_volume_left = vs_volume_left + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != -127 then
                  vs_volume_right = vs_volume_right - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 57 then                -- move volume left to right
               if vs_volume_left != -127 then
                  vs_volume_left = vs_volume_left - 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_left)
               serial_hw_data = " "
               if vs_volume_right != 127 then
                  vs_volume_right = vs_volume_right + 1
               end if
               print_sbyte_dec(serial_hw_data, vs_volume_right)
            elsif serial_data == 58 then                -- slower play speed
               if !(vs_play_speed == 1) then
                  vs_play_speed = vs_play_speed - 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 59 then                -- faster play speed (fast-forward)
               if !(vs_play_speed == 10) then
                  vs_play_speed = vs_play_speed + 1
               end if
               print_word_dec(serial_hw_data, vs_play_speed)
               print_crlf(serial_hw_data)
            elsif serial_data == 60 then                -- get file info, so far
               vs_file_info()                           -- only file type " MP3", "MIDI", etc.
               print_string(serial_hw_data,vs_current_file_type) -- send filetype
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_bitrate)       -- send bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_average_bitrate) -- send avgerage bitrate
               serial_hw_data = " "
               print_dword_dec (serial_hw_data,vs_samplerate)  -- send samplerate
               print_crlf(serial_hw_data)
            elsif serial_data == 61 then                -- MUTE
               vs_mute = TRUE
               print_byte_dec(serial_hw_data, 1)
            elsif serial_data == 62 then                -- NO MUTE
               vs_mute = FALSE
               print_byte_dec(serial_hw_data, vs_mute)
            elsif serial_data == 63 then                -- bass down
               if vs_bass != 0 then
                  vs_bass = vs_bass - 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 64 then                -- bass up
               if vs_bass != 15 then
                  vs_bass = vs_bass + 1
               end if
               print_word_dec(serial_hw_data, vs_bass)
            elsif serial_data == 65 then                -- treble down
               if vs_treble != -8 then
                  vs_treble = vs_treble - 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            elsif serial_data == 66 then                -- treble up
               if vs_treble != 7 then
                  vs_treble = vs_treble + 1
               end if
               print_sword_dec(serial_hw_data, vs_treble)
            end if

            -- send return char
            serial_hw_data = 13
            serial_hw_data = 10
         end if
         vs_data_chip_select = high -- disable vs1053b
         count8 = count8 + 1

      end loop
      -- close the file
      fat32_file_close()
      seperator()
      fat32_print_directory(serial_hw_data, FAT32_PRINT_ALL) -- see the procedure, sends dir listing via serial port
   end if
end loop

Generated by JALlib CHM Help System | Source: mp3_decoder_vs1053b.jal


vw_get_message - JALlib Procedures Help

vw_get_message JALLIB FUNCTION

Signature

function vw_get_message(byte in out len) return bit is

Description

Library for sending and receiving data over an RF Link based
on Virtual Wire. The driver implements a Phase Locked Loop to
increase sensitivity and so extend the range of the connection.
Next to that it uses a special encoding format for the bit
pattern to stay DC neutral. See sources for more information
on Virtual Wire.
A standard 433 MHz transmitter and 433 MHz receiver was used
for testing this driver using a maximum bitrate of 2000 bits/s.
In order to use this driver the main program must have the
following defined (this to make this driver PIC independent):
) An alias for the tranmission pin vw_tx_pin.
) An alias for the receive pin vw_rx_pin.
) Initializing a timer that is used for transmission and
reception. The timer must run at 8 times the bitrate.
) An interrupt routine of the used timer which must call the
vw_service() procedure.
A transmitter only and receiver only version is also available
to save data space and code space for use in smaller PICs.
Note that you have to define a vw_tx_pin and and vw_rx_pin in
order to be able to use this library.
Dependencies: -

Include

To use this procedure, include the library:

include virtual_wire

Parameters

  • len - byte in out

Return Value

bit - Function return value

Example

From sample file: 16f1825_virtual_wire_receiver.jal

-- -----------------------------------------------------------------------------
-- Title: Receiver test program for testing a Virtual Wire connection.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
--
-- Description: This test program receives a message via a Virtual Wire
--              connection using a standard 433 MHz RF receiver module.
--
-- Dependencies: -
--
-- Notes: Do not enable weak-pull up for the pin to which the receiver is
--        connected.
--
-- -----------------------------------------------------------------------------

-- Some compiler pragmas for optimizations
pragma warn all no             -- We do not want to know all compiler warnings
pragma opt variable_reduce yes -- Reduce variables.

include 16f1825              -- target PICmicro

-- This program assumes no crystal but uses the 32 MHz internal oscillator
pragma target clock 32_000_000     -- oscillator frequency 32 MHz

-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PWRTE    enabled         -- Power up timer
pragma target MCLR     internal        -- reset internal
pragma target PLLEN    enabled         -- PLL Enable
pragma target WDT      disabled        -- no watchdog
pragma target LVP      enabled         -- allow Low Voltage Programming

-- Set the internal clock frequency to 32 MHz
OSCCON_IRCF   = 0b1110  -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00    -- Clock determined by FOSC (32 MHz)

-- ------------------------------ Pins -----------------------------------------
-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_0011        -- Weak pull-up for RA0, RA1, RA4, RA5
WPUC = 0b0011_1011        -- Weak pull-up for RC0, RC1, RC3, RC4, RC5, not RC2!
OPTION_REG_WPUEN = FALSE  -- Enable Weak Pull-Up

-- Declaration of the virtual wire receiver pin
alias vw_rx_pin is pin_c2   -- Pin 8. Note. Do not enable weak-pull up.
pin_c2_direction = input

-- Dummy declaration of the virtual wire transmitter pin. Only needed when using
-- the full virtual wire library.
alias vw_tx_pin is pin_c1
pin_c1_direction = output

-- LED indicating transmission of the message. Connect via 330 Ohm resistor.
-- High is LED on.
alias led is pin_a2          -- Pin 11.
pin_a2_direction = output

-- Input pin that determined the bitrate. High is high bitrate.
alias high_bitrate is pin_c0      -- Pin 10.
pin_c0_direction = input

-- Declaration of the USART pins
alias pin_RX_direction is pin_RX_RC5_direction  -- Pin 5.
alias pin_TX_direction is pin_TX_RC4_direction  -- Pin 6.

-- ------------------- Constant and variable declarations ----------------------
const byte VW_MESSAGE_BUFFER  = 25   -- Receive buffer is vw_rx_return_buf
const serial_hw_baudrate      = 9600

-- Selection of bitrates.
const byte VW_SPEED_1000 = 250 -- 1000 bits/second
const byte VW_SPEED_2000 = 125 -- 2000 bits/second

var   byte how_long
var   byte index

include virtual_wire         -- Full driver version
--include virtual_wire_receiver   -- Receiver only version. Saves memory.

-- --------------------- Functions and Procedures ------------------------------
-- These two procedures are needed for using the virtual wire library. The
-- timer can be any timer of the PIC.
procedure timer2_setup(byte in bitrate) is
  -- The timer runs at Fosc/4 so 32.000.000 Hz --> 8 MHz.
  -- If we prescale by 4 then it runs at 2 MHz. With a bit time of 1 ms
  -- (1000 bit/s) and a sample time of VW_RX_SAMPLES_PER_BIT (=8) gives
  -- 2 MHz / 250 = 8 kHz or 125 us. For 2000 bits/s the reload value has to
  -- be 125 (gives 16 kHz divided by 8 samples gives 2000 bits/s)
  T2CON_T2CKPS  = 0b01   -- Prescale = 4
  T2CON_T2OUTPS = 0b0000 -- Postcale = 0
  PR2 = bitrate          -- Compare value
  PIE1_TMR2IE   = TRUE   -- Enable Timer 2 interrupt
  T2CON_TMR2ON  = TRUE   -- Start Timer
  -- Enable all interrupts.
  INTCON_PEIE = TRUE     -- Peripheral interrupts enabled.
  INTCON_GIE  = TRUE     -- Globale interrupt enabled
end procedure

procedure timer2_interrupt() is pragma interrupt
  -- Timer procedure. Call the virtual wire serviice routine if needed.
  if PIR1_TMR2IF then
     PIR1_TMR2IF = FALSE
     -- Call the virtual wire service routine.
     vw_service()
  end if
end procedure

-- ------------------------------ Main Program  --------------------------------
include serial_hardware
enable_digital_io() -- Make all pins digital I/O
serial_hw_init()
vw_init()
-- Setup the timer and the bitrate.
if high_bitrate then
  timer2_setup(VW_SPEED_2000)         -- High bitrate.
else
  timer2_setup(VW_SPEED_1000)         -- Low bitrate
end if
vw_rx_start()          -- Start the receiver pll running.

led = false

forever loop
  how_long = VW_MESSAGE_BUFFER -- Maximum number of bytes to copy.
  if vw_get_message(how_long) then
    led = true
    -- Variable 'how_long' now holds the actual number of received bytes.
    for how_long using index loop
       serial_hw_write(vw_rx_return_buf[index])
    end loop
    led = false
  end if
end loop

Generated by JALlib CHM Help System | Source: virtual_wire.jal


vw_init - JALlib Procedures Help

vw_init JALLIB PROCEDURE

Signature

procedure vw_init() is

Description

Library for sending and receiving data over an RF Link based
on Virtual Wire. The driver implements a Phase Locked Loop to
increase sensitivity and so extend the range of the connection.
Next to that it uses a special encoding format for the bit
pattern to stay DC neutral. See sources for more information
on Virtual Wire.
A standard 433 MHz transmitter and 433 MHz receiver was used
for testing this driver using a maximum bitrate of 2000 bits/s.
In order to use this driver the main program must have the
following defined (this to make this driver PIC independent):
) An alias for the tranmission pin vw_tx_pin.
) An alias for the receive pin vw_rx_pin.
) Initializing a timer that is used for transmission and
reception. The timer must run at 8 times the bitrate.
) An interrupt routine of the used timer which must call the
vw_service() procedure.
A transmitter only and receiver only version is also available
to save data space and code space for use in smaller PICs.
Note that you have to define a vw_tx_pin and and vw_rx_pin in
order to be able to use this library.
Dependencies: -

Include

To use this procedure, include the library:

include virtual_wire

Parameters

None

Return Value

None

Example

From sample file: 16f1825_virtual_wire_receiver.jal

-- -----------------------------------------------------------------------------
-- Title: Receiver test program for testing a Virtual Wire connection.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
--
-- Description: This test program receives a message via a Virtual Wire
--              connection using a standard 433 MHz RF receiver module.
--
-- Dependencies: -
--
-- Notes: Do not enable weak-pull up for the pin to which the receiver is
--        connected.
--
-- -----------------------------------------------------------------------------

-- Some compiler pragmas for optimizations
pragma warn all no             -- We do not want to know all compiler warnings
pragma opt variable_reduce yes -- Reduce variables.

include 16f1825              -- target PICmicro

-- This program assumes no crystal but uses the 32 MHz internal oscillator
pragma target clock 32_000_000     -- oscillator frequency 32 MHz

-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PWRTE    enabled         -- Power up timer
pragma target MCLR     internal        -- reset internal
pragma target PLLEN    enabled         -- PLL Enable
pragma target WDT      disabled        -- no watchdog
pragma target LVP      enabled         -- allow Low Voltage Programming

-- Set the internal clock frequency to 32 MHz
OSCCON_IRCF   = 0b1110  -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00    -- Clock determined by FOSC (32 MHz)

-- ------------------------------ Pins -----------------------------------------
-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_0011        -- Weak pull-up for RA0, RA1, RA4, RA5
WPUC = 0b0011_1011        -- Weak pull-up for RC0, RC1, RC3, RC4, RC5, not RC2!
OPTION_REG_WPUEN = FALSE  -- Enable Weak Pull-Up

-- Declaration of the virtual wire receiver pin
alias vw_rx_pin is pin_c2   -- Pin 8. Note. Do not enable weak-pull up.
pin_c2_direction = input

-- Dummy declaration of the virtual wire transmitter pin. Only needed when using
-- the full virtual wire library.
alias vw_tx_pin is pin_c1
pin_c1_direction = output

-- LED indicating transmission of the message. Connect via 330 Ohm resistor.
-- High is LED on.
alias led is pin_a2          -- Pin 11.
pin_a2_direction = output

-- Input pin that determined the bitrate. High is high bitrate.
alias high_bitrate is pin_c0      -- Pin 10.
pin_c0_direction = input

-- Declaration of the USART pins
alias pin_RX_direction is pin_RX_RC5_direction  -- Pin 5.
alias pin_TX_direction is pin_TX_RC4_direction  -- Pin 6.

-- ------------------- Constant and variable declarations ----------------------
const byte VW_MESSAGE_BUFFER  = 25   -- Receive buffer is vw_rx_return_buf
const serial_hw_baudrate      = 9600

-- Selection of bitrates.
const byte VW_SPEED_1000 = 250 -- 1000 bits/second
const byte VW_SPEED_2000 = 125 -- 2000 bits/second

var   byte how_long
var   byte index

include virtual_wire         -- Full driver version
--include virtual_wire_receiver   -- Receiver only version. Saves memory.

-- --------------------- Functions and Procedures ------------------------------
-- These two procedures are needed for using the virtual wire library. The
-- timer can be any timer of the PIC.
procedure timer2_setup(byte in bitrate) is
  -- The timer runs at Fosc/4 so 32.000.000 Hz --> 8 MHz.
  -- If we prescale by 4 then it runs at 2 MHz. With a bit time of 1 ms
  -- (1000 bit/s) and a sample time of VW_RX_SAMPLES_PER_BIT (=8) gives
  -- 2 MHz / 250 = 8 kHz or 125 us. For 2000 bits/s the reload value has to
  -- be 125 (gives 16 kHz divided by 8 samples gives 2000 bits/s)
  T2CON_T2CKPS  = 0b01   -- Prescale = 4
  T2CON_T2OUTPS = 0b0000 -- Postcale = 0
  PR2 = bitrate          -- Compare value
  PIE1_TMR2IE   = TRUE   -- Enable Timer 2 interrupt
  T2CON_TMR2ON  = TRUE   -- Start Timer
  -- Enable all interrupts.
  INTCON_PEIE = TRUE     -- Peripheral interrupts enabled.
  INTCON_GIE  = TRUE     -- Globale interrupt enabled
end procedure

procedure timer2_interrupt() is pragma interrupt
  -- Timer procedure. Call the virtual wire serviice routine if needed.
  if PIR1_TMR2IF then
     PIR1_TMR2IF = FALSE
     -- Call the virtual wire service routine.
     vw_service()
  end if
end procedure

-- ------------------------------ Main Program  --------------------------------
include serial_hardware
enable_digital_io() -- Make all pins digital I/O
serial_hw_init()
vw_init()
-- Setup the timer and the bitrate.
if high_bitrate then
  timer2_setup(VW_SPEED_2000)         -- High bitrate.
else
  timer2_setup(VW_SPEED_1000)         -- Low bitrate
end if
vw_rx_start()          -- Start the receiver pll running.

led = false

forever loop
  how_long = VW_MESSAGE_BUFFER -- Maximum number of bytes to copy.
  if vw_get_message(how_long) then
    led = true
    -- Variable 'how_long' now holds the actual number of received bytes.
    for how_long using index loop
       serial_hw_write(vw_rx_return_buf[index])
    end loop
    led = false
  end if
end loop

Generated by JALlib CHM Help System | Source: virtual_wire.jal


vw_rx_start - JALlib Procedures Help

vw_rx_start JALLIB PROCEDURE

Signature

procedure vw_rx_start() is

Description

Library for sending and receiving data over an RF Link based
on Virtual Wire. The driver implements a Phase Locked Loop to
increase sensitivity and so extend the range of the connection.
Next to that it uses a special encoding format for the bit
pattern to stay DC neutral. See sources for more information
on Virtual Wire.
A standard 433 MHz transmitter and 433 MHz receiver was used
for testing this driver using a maximum bitrate of 2000 bits/s.
In order to use this driver the main program must have the
following defined (this to make this driver PIC independent):
) An alias for the tranmission pin vw_tx_pin.
) An alias for the receive pin vw_rx_pin.
) Initializing a timer that is used for transmission and
reception. The timer must run at 8 times the bitrate.
) An interrupt routine of the used timer which must call the
vw_service() procedure.
A transmitter only and receiver only version is also available
to save data space and code space for use in smaller PICs.
Note that you have to define a vw_tx_pin and and vw_rx_pin in
order to be able to use this library.
Dependencies: -

Include

To use this procedure, include the library:

include virtual_wire

Parameters

None

Return Value

None

Example

From sample file: 16f1825_virtual_wire_receiver.jal

-- -----------------------------------------------------------------------------
-- Title: Receiver test program for testing a Virtual Wire connection.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
--
-- Description: This test program receives a message via a Virtual Wire
--              connection using a standard 433 MHz RF receiver module.
--
-- Dependencies: -
--
-- Notes: Do not enable weak-pull up for the pin to which the receiver is
--        connected.
--
-- -----------------------------------------------------------------------------

-- Some compiler pragmas for optimizations
pragma warn all no             -- We do not want to know all compiler warnings
pragma opt variable_reduce yes -- Reduce variables.

include 16f1825              -- target PICmicro

-- This program assumes no crystal but uses the 32 MHz internal oscillator
pragma target clock 32_000_000     -- oscillator frequency 32 MHz

-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PWRTE    enabled         -- Power up timer
pragma target MCLR     internal        -- reset internal
pragma target PLLEN    enabled         -- PLL Enable
pragma target WDT      disabled        -- no watchdog
pragma target LVP      enabled         -- allow Low Voltage Programming

-- Set the internal clock frequency to 32 MHz
OSCCON_IRCF   = 0b1110  -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00    -- Clock determined by FOSC (32 MHz)

-- ------------------------------ Pins -----------------------------------------
-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_0011        -- Weak pull-up for RA0, RA1, RA4, RA5
WPUC = 0b0011_1011        -- Weak pull-up for RC0, RC1, RC3, RC4, RC5, not RC2!
OPTION_REG_WPUEN = FALSE  -- Enable Weak Pull-Up

-- Declaration of the virtual wire receiver pin
alias vw_rx_pin is pin_c2   -- Pin 8. Note. Do not enable weak-pull up.
pin_c2_direction = input

-- Dummy declaration of the virtual wire transmitter pin. Only needed when using
-- the full virtual wire library.
alias vw_tx_pin is pin_c1
pin_c1_direction = output

-- LED indicating transmission of the message. Connect via 330 Ohm resistor.
-- High is LED on.
alias led is pin_a2          -- Pin 11.
pin_a2_direction = output

-- Input pin that determined the bitrate. High is high bitrate.
alias high_bitrate is pin_c0      -- Pin 10.
pin_c0_direction = input

-- Declaration of the USART pins
alias pin_RX_direction is pin_RX_RC5_direction  -- Pin 5.
alias pin_TX_direction is pin_TX_RC4_direction  -- Pin 6.

-- ------------------- Constant and variable declarations ----------------------
const byte VW_MESSAGE_BUFFER  = 25   -- Receive buffer is vw_rx_return_buf
const serial_hw_baudrate      = 9600

-- Selection of bitrates.
const byte VW_SPEED_1000 = 250 -- 1000 bits/second
const byte VW_SPEED_2000 = 125 -- 2000 bits/second

var   byte how_long
var   byte index

include virtual_wire         -- Full driver version
--include virtual_wire_receiver   -- Receiver only version. Saves memory.

-- --------------------- Functions and Procedures ------------------------------
-- These two procedures are needed for using the virtual wire library. The
-- timer can be any timer of the PIC.
procedure timer2_setup(byte in bitrate) is
  -- The timer runs at Fosc/4 so 32.000.000 Hz --> 8 MHz.
  -- If we prescale by 4 then it runs at 2 MHz. With a bit time of 1 ms
  -- (1000 bit/s) and a sample time of VW_RX_SAMPLES_PER_BIT (=8) gives
  -- 2 MHz / 250 = 8 kHz or 125 us. For 2000 bits/s the reload value has to
  -- be 125 (gives 16 kHz divided by 8 samples gives 2000 bits/s)
  T2CON_T2CKPS  = 0b01   -- Prescale = 4
  T2CON_T2OUTPS = 0b0000 -- Postcale = 0
  PR2 = bitrate          -- Compare value
  PIE1_TMR2IE   = TRUE   -- Enable Timer 2 interrupt
  T2CON_TMR2ON  = TRUE   -- Start Timer
  -- Enable all interrupts.
  INTCON_PEIE = TRUE     -- Peripheral interrupts enabled.
  INTCON_GIE  = TRUE     -- Globale interrupt enabled
end procedure

procedure timer2_interrupt() is pragma interrupt
  -- Timer procedure. Call the virtual wire serviice routine if needed.
  if PIR1_TMR2IF then
     PIR1_TMR2IF = FALSE
     -- Call the virtual wire service routine.
     vw_service()
  end if
end procedure

-- ------------------------------ Main Program  --------------------------------
include serial_hardware
enable_digital_io() -- Make all pins digital I/O
serial_hw_init()
vw_init()
-- Setup the timer and the bitrate.
if high_bitrate then
  timer2_setup(VW_SPEED_2000)         -- High bitrate.
else
  timer2_setup(VW_SPEED_1000)         -- Low bitrate
end if
vw_rx_start()          -- Start the receiver pll running.

led = false

forever loop
  how_long = VW_MESSAGE_BUFFER -- Maximum number of bytes to copy.
  if vw_get_message(how_long) then
    led = true
    -- Variable 'how_long' now holds the actual number of received bytes.
    for how_long using index loop
       serial_hw_write(vw_rx_return_buf[index])
    end loop
    led = false
  end if
end loop

Generated by JALlib CHM Help System | Source: virtual_wire.jal


vw_send - JALlib Procedures Help

vw_send JALLIB FUNCTION

Signature

function vw_send(byte in buf[], byte in len) return bit is

Description

Library for sending and receiving data over an RF Link based
on Virtual Wire. The driver implements a Phase Locked Loop to
increase sensitivity and so extend the range of the connection.
Next to that it uses a special encoding format for the bit
pattern to stay DC neutral. See sources for more information
on Virtual Wire.
A standard 433 MHz transmitter and 433 MHz receiver was used
for testing this driver using a maximum bitrate of 2000 bits/s.
In order to use this driver the main program must have the
following defined (this to make this driver PIC independent):
) An alias for the tranmission pin vw_tx_pin.
) An alias for the receive pin vw_rx_pin.
) Initializing a timer that is used for transmission and
reception. The timer must run at 8 times the bitrate.
) An interrupt routine of the used timer which must call the
vw_service() procedure.
A transmitter only and receiver only version is also available
to save data space and code space for use in smaller PICs.
Note that you have to define a vw_tx_pin and and vw_rx_pin in
order to be able to use this library.
Dependencies: -

Include

To use this procedure, include the library:

include virtual_wire

Parameters

  • buf[] - byte in
  • len - byte in

Return Value

bit - Function return value

Example

From sample file: 12f617_virtual_wire_transmitter.jal

-- -----------------------------------------------------------------------------
-- Title: Transmitter test program for testing a Virtual Wire connection.
--
-- Author: Rob Jansen, Copyright (c) 2019..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
--
-- Description: This test program transmits one byte via a Virtual Wire
--              connection using a standard 433 MHz RF transmitter module.
--              The value of the byte is depending on the value of an input
--              pin and can be 0x00 or 0xFF.
--              This sample program shows that the virtual wire library can be
--              used on smaller PICs too. It uses the transmit only version.
--
-- Dependencies: -
--
-- Notes: -
--
-- -----------------------------------------------------------------------------

-- Some compiler pragmas for optimizations
pragma warn all no             -- We do not want to know all compiler warnings
pragma opt variable_reduce yes -- Reduce variables.

include 12f617                 -- target PICmicro

; Use internal clock and internal reset.
pragma target OSC    INTOSC_NOCLKOUT -- Internal Clock
pragma target PWRTE  ENABLED         -- Power up timer
pragma target MCLR   INTERNAL        -- Reset internal
pragma target WDT    DISABLED        -- No watchdog
pragma target IOSCFS F8MHZ           -- Set internal oscillator to 8 MHz
pragma target clock  8_000_000       -- oscillator frequency 8 MHz

-- ------------------------------ Pins -----------------------------------------
; Transmitter pin for virtual wire.
alias vw_tx_pin is pin_GP0    -- Pin 7. Data transmission pin.
pin_GP0_direction = output

alias high_bitrate is pin_GP3 -- Pin 4. Enabled when high.
Pin_GP3_Direction = input

alias input_value is Pin_GP4  -- Pin 3.
Pin_GP4_Direction = input

; Enable weak pull up for all ports.
WPU = 0b0011_1111         -- Weak pull-up enabled for all port pins.
OPTION_REG_NGPPU = FALSE  -- Enable Weak Pull-Up

-- ------------------- Constant and variable declarations ----------------------
const byte VW_MESSAGE_BUFFER = 1 -- We only send one byte.

-- Selection of bitrates.
const byte VW_SPEED_1000 = 250   -- 1000 bits/second
const byte VW_SPEED_2000 = 125   -- 2000 bits/second

var byte tx_buf[VW_MESSAGE_BUFFER]

include virtual_wire_transmitter -- Transmitter only version. Saves memory.

-- --------------------- Functions and Procedures ------------------------------
-- These two procedures are needed for using the virtual wire library. The
-- timer can be any timer of the PIC.
procedure timer2_setup(byte in bitrate) is
  -- The timer runs at Fosc/4 so 8.000.000 Hz --> 2 MHz.
  -- If we prescale by 1 then it stays at 2 MHz. With a bit time of 1 ms
  -- (1000 bit/s) and a sample time of VW_RX_SAMPLES_PER_BIT (=8) gives
  -- 2 MHz / 250 = 8 kHz or 125 us. For 2000 bits/s the reload value has to
  -- be 125 (gives 16 kHz divided by 8 samples gives 2000 bits/s)
  T2CON_T2CKPS  = 0b00   -- Prescale = 1
  T2CON_TOUTPS  = 0b0000 -- Postcale = 0
  PR2 = bitrate          -- Compare value
  PIE1_TMR2IE   = TRUE   -- Enable Timer 2 interrupt
  T2CON_TMR2ON  = TRUE   -- Start Timer
  -- Enable all interrupts.
  INTCON_PEIE = TRUE     -- Peripheral interrupts enabled.
  INTCON_GIE  = TRUE     -- Globale interrupt enabled
end procedure

procedure timer2_interrupt() is pragma interrupt
  -- Timer procedure. Call the virtual wire serviice routine if needed.
  if PIR1_TMR2IF then
     PIR1_TMR2IF = FALSE
     -- Call the virtual wire service routine.
     vw_service()
  end if
end procedure

-- ------------------------------ Main Program  --------------------------------
enable_digital_io()

-- Initialize virtual wire driver.
vw_init()
if high_bitrate then
  timer2_setup(VW_SPEED_2000)         -- High bitrate.
else
  timer2_setup(VW_SPEED_1000)         -- Low bitrate
end if

forever loop
   -- Wait some time before sending new messages.
   _usec_delay(100_000)

  if !vw_tx_active
  then
     -- Transmitter ready, send data.
     if input_value then
        tx_buf[0] = 0xFF
     else
        tx_buf[0] = 0x00
     end if
     if vw_send(tx_buf, VW_MESSAGE_BUFFER) then
       -- Empty block.
     end if
  end if

end loop

Generated by JALlib CHM Help System | Source: virtual_wire.jal


vw_service - JALlib Procedures Help

vw_service JALLIB PROCEDURE

Signature

procedure vw_service() is

Description

Library for sending and receiving data over an RF Link based
on Virtual Wire. The driver implements a Phase Locked Loop to
increase sensitivity and so extend the range of the connection.
Next to that it uses a special encoding format for the bit
pattern to stay DC neutral. See sources for more information
on Virtual Wire.
A standard 433 MHz transmitter and 433 MHz receiver was used
for testing this driver using a maximum bitrate of 2000 bits/s.
In order to use this driver the main program must have the
following defined (this to make this driver PIC independent):
) An alias for the tranmission pin vw_tx_pin.
) An alias for the receive pin vw_rx_pin.
) Initializing a timer that is used for transmission and
reception. The timer must run at 8 times the bitrate.
) An interrupt routine of the used timer which must call the
vw_service() procedure.
A transmitter only and receiver only version is also available
to save data space and code space for use in smaller PICs.
Note that you have to define a vw_tx_pin and and vw_rx_pin in
order to be able to use this library.
Dependencies: -

Include

To use this procedure, include the library:

include virtual_wire

Parameters

None

Return Value

None

Example

From sample file: 16f1825_virtual_wire_receiver.jal

-- -----------------------------------------------------------------------------
-- Title: Receiver test program for testing a Virtual Wire connection.
--
-- Author: Rob Jansen, Copyright (c) 2018..2019, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.5r2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Sources: http://www.airspayce.com/mikem/arduino/VirtualWire.pdf
--
-- Description: This test program receives a message via a Virtual Wire
--              connection using a standard 433 MHz RF receiver module.
--
-- Dependencies: -
--
-- Notes: Do not enable weak-pull up for the pin to which the receiver is
--        connected.
--
-- -----------------------------------------------------------------------------

-- Some compiler pragmas for optimizations
pragma warn all no             -- We do not want to know all compiler warnings
pragma opt variable_reduce yes -- Reduce variables.

include 16f1825              -- target PICmicro

-- This program assumes no crystal but uses the 32 MHz internal oscillator
pragma target clock 32_000_000     -- oscillator frequency 32 MHz

-- Configuration memory settings (fuses)
pragma target OSC      INTOSC_NOCLKOUT -- Internal Clock
pragma target PWRTE    enabled         -- Power up timer
pragma target MCLR     internal        -- reset internal
pragma target PLLEN    enabled         -- PLL Enable
pragma target WDT      disabled        -- no watchdog
pragma target LVP      enabled         -- allow Low Voltage Programming

-- Set the internal clock frequency to 32 MHz
OSCCON_IRCF   = 0b1110  -- Set 32 MHz (uses 8 MHz source)
OSCCON_SCS    = 0b00    -- Clock determined by FOSC (32 MHz)

-- ------------------------------ Pins -----------------------------------------
-- Enable weak pull up for all unused ports since some inputs are not connected
WPUA = 0b0011_0011        -- Weak pull-up for RA0, RA1, RA4, RA5
WPUC = 0b0011_1011        -- Weak pull-up for RC0, RC1, RC3, RC4, RC5, not RC2!
OPTION_REG_WPUEN = FALSE  -- Enable Weak Pull-Up

-- Declaration of the virtual wire receiver pin
alias vw_rx_pin is pin_c2   -- Pin 8. Note. Do not enable weak-pull up.
pin_c2_direction = input

-- Dummy declaration of the virtual wire transmitter pin. Only needed when using
-- the full virtual wire library.
alias vw_tx_pin is pin_c1
pin_c1_direction = output

-- LED indicating transmission of the message. Connect via 330 Ohm resistor.
-- High is LED on.
alias led is pin_a2          -- Pin 11.
pin_a2_direction = output

-- Input pin that determined the bitrate. High is high bitrate.
alias high_bitrate is pin_c0      -- Pin 10.
pin_c0_direction = input

-- Declaration of the USART pins
alias pin_RX_direction is pin_RX_RC5_direction  -- Pin 5.
alias pin_TX_direction is pin_TX_RC4_direction  -- Pin 6.

-- ------------------- Constant and variable declarations ----------------------
const byte VW_MESSAGE_BUFFER  = 25   -- Receive buffer is vw_rx_return_buf
const serial_hw_baudrate      = 9600

-- Selection of bitrates.
const byte VW_SPEED_1000 = 250 -- 1000 bits/second
const byte VW_SPEED_2000 = 125 -- 2000 bits/second

var   byte how_long
var   byte index

include virtual_wire         -- Full driver version
--include virtual_wire_receiver   -- Receiver only version. Saves memory.

-- --------------------- Functions and Procedures ------------------------------
-- These two procedures are needed for using the virtual wire library. The
-- timer can be any timer of the PIC.
procedure timer2_setup(byte in bitrate) is
  -- The timer runs at Fosc/4 so 32.000.000 Hz --> 8 MHz.
  -- If we prescale by 4 then it runs at 2 MHz. With a bit time of 1 ms
  -- (1000 bit/s) and a sample time of VW_RX_SAMPLES_PER_BIT (=8) gives
  -- 2 MHz / 250 = 8 kHz or 125 us. For 2000 bits/s the reload value has to
  -- be 125 (gives 16 kHz divided by 8 samples gives 2000 bits/s)
  T2CON_T2CKPS  = 0b01   -- Prescale = 4
  T2CON_T2OUTPS = 0b0000 -- Postcale = 0
  PR2 = bitrate          -- Compare value
  PIE1_TMR2IE   = TRUE   -- Enable Timer 2 interrupt
  T2CON_TMR2ON  = TRUE   -- Start Timer
  -- Enable all interrupts.
  INTCON_PEIE = TRUE     -- Peripheral interrupts enabled.
  INTCON_GIE  = TRUE     -- Globale interrupt enabled
end procedure

procedure timer2_interrupt() is pragma interrupt
  -- Timer procedure. Call the virtual wire serviice routine if needed.
  if PIR1_TMR2IF then
     PIR1_TMR2IF = FALSE
     -- Call the virtual wire service routine.
     vw_service()
  end if
end procedure

-- ------------------------------ Main Program  --------------------------------
include serial_hardware
enable_digital_io() -- Make all pins digital I/O
serial_hw_init()
vw_init()
-- Setup the timer and the bitrate.
if high_bitrate then
  timer2_setup(VW_SPEED_2000)         -- High bitrate.
else
  timer2_setup(VW_SPEED_1000)         -- Low bitrate
end if
vw_rx_start()          -- Start the receiver pll running.

led = false

forever loop
  how_long = VW_MESSAGE_BUFFER -- Maximum number of bytes to copy.
  if vw_get_message(how_long) then
    led = true
    -- Variable 'how_long' now holds the actual number of received bytes.
    for how_long using index loop
       serial_hw_write(vw_rx_return_buf[index])
    end loop
    led = false
  end if
end loop

Generated by JALlib CHM Help System | Source: virtual_wire.jal


ws2812b_all_color - JALlib Procedures Help

ws2812b_all_color JALLIB PROCEDURE

Signature

procedure ws2812b_all_color(byte in g, byte in r, byte in b) is

Description

Title: Set all LEDS to same color
Input: 3 colors (bytes)
Notes: It is assumed that the chain of WS2812Bs has WS2812B_NUM pixels

Include

To use this procedure, include the library:

include ws2812b_common

Parameters

  • g - byte in
  • r - byte in
  • b - byte in

Return Value

None

Example

From sample file: 18f14k22_ws2812b_async.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with USART Asynchronous
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 18f14k22 with INTOSC at Fosc = 64 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 18f14k22

-- Internal oscillator at 16 MHz with PLL enabled -> 64 MHz
pragma target clock    64_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target PCLKEN   ENABLED            -- primary clock
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target IESO     DISABLED           -- no osc switchover
pragma target PWRTE    ENABLED            -- power up delay
pragma target BROWNOUT DISABLED           -- no brownout
pragma target WDT      CONTROL            -- watchdog software controlled
pragma target HFOFST   ENABLED            -- wait for stable osc
pragma target MCLR     EXTERNAL           -- reset externally
pragma target LVP      ENABLED            -- allow LVP
pragma target DEBUG    DISABLED           -- no debug

WDTCON_SWDTEN = DISABLED                  -- WDT disabled

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled

enable_digital_io()                       -- all pins digital

alias led is pin_A0                       -- being alive signal
pin_A0_direction = OUTPUT
led = ON

const WS2812B_NUM = 30

include ws2812b_async                     -- support library (USART ASYNC variant)
ws2812b_async_init()                      -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: ws2812b_common.jal


ws2812b_async.jal - JALLIB Library Documentation

ws2812b_async.jal JALLIB LIBRARY

Title

Transmit a byte (with 3 WS2812B 'bits')

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to control a chain of WS2812Bs
This library uses the USART module with Asynchronous protocol.
- A PIC with Fosc of at least 32 MHz is required.
- A high speed USART is required (BRG16 bit in BAUDCON)
- The first or only USART interface is used and initialized automatically.
- The USART must be able to invert the polarity of the USART output
(have a CKTXP or TXCKP bit in BAUDCON, like with many 18Fs,
or the SCKP bit in BAUDCON like the midrnage and other 18Fs).
Alternatively an external signal inverter is required.
- The DIN wire of the WS2812B chain must be connected to pin_TX of the PIC
and this pin must be configured for digital I/O.

Notes

- The pin_TX/CK may have to be configured with Peripheral Pin Select (PPS)
or Alternate Pin Function (APFCON_TXCKSEL).
- pin_RX is not used.
- Initialize the interface with procedure ws2812b_async_init().
- The number of WS2812Bs in the chain must be specified, e.g.:
const byte WS2812B_NUM = 30 -- for 30 chained WS2812Bs
- The user program should contain 3 byte arrays of WS2812B_NUM bytes each, e.g.:
var byte agreen[WS2812B_NUM]
var byte ared[WS2812B_NUM]
var byte ablue[WS2812B_NUM]
and call the procedure ws2812b_refresh() to pass the current color settings
to the WS2812B LEDs.
- Procedure ws2812b_all_color() can be used to set all LEDs to the same color
while keeping the color settings in the arrays unchanged.
Dependencies: ws2812b_common.jal
- Warnings temporary(?) commented out.
-----------------------------------------------------------------------------

========= 'private' procedures =====================

----------------------------------------------------------------------------
- We do not wait for completion immediately after a write, but
wait for completion of the previous write before the next write!
This allows to execute instructions during the transfer time to
prepare for the transmission of the next byte.
----------------------------------------------------------------------------

Routines

  • _transfer_byte - Procedure
  • _ws2812b_write_pixel - Procedure
  • ws2812b_async_init - Procedure


ws2812b_async_init - JALlib Procedures Help

ws2812b_async_init JALLIB PROCEDURE

Signature

procedure ws2812b_async_init() is

Description

Title: Initialize the USART for Asynchronous transmit at the required speed
Input: (none)

Include

To use this procedure, include the library:

include ws2812b_async

Parameters

None

Return Value

None

Example

From sample file: 18f14k22_ws2812b_async.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with USART Asynchronous
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 18f14k22 with INTOSC at Fosc = 64 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 18f14k22

-- Internal oscillator at 16 MHz with PLL enabled -> 64 MHz
pragma target clock    64_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target PCLKEN   ENABLED            -- primary clock
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target IESO     DISABLED           -- no osc switchover
pragma target PWRTE    ENABLED            -- power up delay
pragma target BROWNOUT DISABLED           -- no brownout
pragma target WDT      CONTROL            -- watchdog software controlled
pragma target HFOFST   ENABLED            -- wait for stable osc
pragma target MCLR     EXTERNAL           -- reset externally
pragma target LVP      ENABLED            -- allow LVP
pragma target DEBUG    DISABLED           -- no debug

WDTCON_SWDTEN = DISABLED                  -- WDT disabled

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled

enable_digital_io()                       -- all pins digital

alias led is pin_A0                       -- being alive signal
pin_A0_direction = OUTPUT
led = ON

const WS2812B_NUM = 30

include ws2812b_async                     -- support library (USART ASYNC variant)
ws2812b_async_init()                      -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: ws2812b_async.jal


ws2812b_common.jal - JALLIB Library Documentation

ws2812b_common.jal JALLIB LIBRARY

Title

Common part of libraries supporting a chain of WS2812B chips

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Common part of several libraries to control a chain of WS2812Bs
(RGB LEDs with builtin WS2811).
See the description of the implementation variants for user guidance.
.
The main differences between the variants of the WS2812B libraries are:
- The libraries using the PIC hardware (USART or MSSP modules)
produce a signal which is generally closer to the specifications
in the datasheet than with bit-banging. This is probably the effect
of the buffering: while the MSSP or USART is busy with transmitting
a byte (with 2 or 3 WS2812B 'bits') the processor is available
to prepare the output for the next couple of bits to be transmitted.
- A disadvantage of the bit-banging method is that the compiler
generates somewhat different code for the 18Fs than for the midrange
and enhanced midrange PICs, disrupting the bit timing somewhat.
This may cause instable operation.
- When using MSSP or USART only one specific pin produces the control signal,
while with bit-banging any digital output pin can be used.
- With SPI and bit-banging the control signal can be generated with the
correct polarity. Since a USART uses negative polarity for data the signal
must be inverted. This can be done with an external circuit (a simple
one transistor inverter will do) and for Synchronous protocol this is
the only option. For Asynchronous protocol this can be used too, but some
PICs have a builtin inverter. When available the library will use
this feature to produce a positive signal (with the BAUDCON_TXCKP bit)
and no external inverter is needed.
Dependencies:

Notes

- Interrupts are disabled during transmission of data to the chain.
-----------------------------------------------------------------------------

--- sanity check ----------------------------------

--- WS2812B constants -----------------------------

Routines

  • ws2812b_all_color - Procedure
  • ws2812b_refresh - Procedure


ws2812b_refresh - JALlib Procedures Help

ws2812b_refresh JALLIB PROCEDURE

Signature

procedure ws2812b_refresh(byte in g[], byte in r[], byte in b[]) is

Description

Title: Refresh contents of all pixels of the WS2812B chain.
Input: 3 Arrays for green, red and blue
Notes: It is assumed that the arrays have a length of WS2812B_NUM bytes

Include

To use this procedure, include the library:

include ws2812b_common

Parameters

  • g[] - byte in
  • r[] - byte in
  • b[] - byte in

Return Value

None

Example

From sample file: 18f14k22_ws2812b_async.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with USART Asynchronous
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 18f14k22 with INTOSC at Fosc = 64 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 18f14k22

-- Internal oscillator at 16 MHz with PLL enabled -> 64 MHz
pragma target clock    64_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target PCLKEN   ENABLED            -- primary clock
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target IESO     DISABLED           -- no osc switchover
pragma target PWRTE    ENABLED            -- power up delay
pragma target BROWNOUT DISABLED           -- no brownout
pragma target WDT      CONTROL            -- watchdog software controlled
pragma target HFOFST   ENABLED            -- wait for stable osc
pragma target MCLR     EXTERNAL           -- reset externally
pragma target LVP      ENABLED            -- allow LVP
pragma target DEBUG    DISABLED           -- no debug

WDTCON_SWDTEN = DISABLED                  -- WDT disabled

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled

enable_digital_io()                       -- all pins digital

alias led is pin_A0                       -- being alive signal
pin_A0_direction = OUTPUT
led = ON

const WS2812B_NUM = 30

include ws2812b_async                     -- support library (USART ASYNC variant)
ws2812b_async_init()                      -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: ws2812b_common.jal


ws2812b_spi.jal - JALLIB Library Documentation

ws2812b_spi.jal JALLIB LIBRARY

Title

Transmit a byte (with 2 WS2812B 'bits')

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to control a chain of WS2812Bs
This library uses the MSSP module with SPI-master protocol.
- A PIC with Fosc of at least 32 MHz and MSSP module is required.
- The MSSP module must have the capability to set the baudrate in SPI master mode
with SSPCON1_SSPM = 0b1010 : SPI Master mode, clock = FOSC/(4 * (SSPADD+1)).
like with the 18f25k22 (note: e.g. with the 18f14k22 this works only for I2C).
This requirement cannot be checked by the library, check the datasheet!
- The DIN wire of the WS2812B must be connected to pin_SDO of the PIC
The pin must be configured for digital output.

Notes

- The pin_SDO may have to be configured with Peripheral Pin Select (PPS)
or Alternate Pin Function (APFCON_SDOSEL).
- The SDI and SCK pins are not used.
- Initialize the interface with procedure ws2812b_async_init().
- The number of WS2812Bs in the chain must be defined, e.g.:
const byte WS2812B_NUM = 30 -- for 30 chained WS2812Bs
- The user program should contain 3 byte arrays of WS2812B_NUM bytes each, e.g.:
var byte agreen[WS2812B_NUM]
var byte ared[WS2812B_NUM]
var byte ablue[WS2812B_NUM]
and call the procedure ws2812b_refresh() to pass the current color settings
to the WS2812B LEDs.
- Procedure ws2812b_all_color() can be used to set all LEDs to the same color
while keeping the color settings in the array unchanged.
Dependencies: ws2812b_common.jal
- Warnings are temporary(?) commented out.
-----------------------------------------------------------------------------

========= 'private' procedures =====================

----------------------------------------------------------------------------
- We do not wait for completion immediately after a write, but
wait for completion of the previous write before the next write!
This allows to execute instructions during the transfer time to
prepare for the transmission of the next byte.
----------------------------------------------------------------------------

Routines

  • _transfer_byte - Procedure
  • _ws2812b_write_color - Procedure
  • _ws2812b_write_pixel - Procedure
  • ws2812b_spi_init - Procedure


ws2812b_spi_init - JALlib Procedures Help

ws2812b_spi_init JALLIB PROCEDURE

Signature

procedure ws2812b_spi_init() is

Description

Title: Initialize the MSSP for SPI master transmit at the required speed
Input: (none)

Include

To use this procedure, include the library:

include ws2812b_spi

Parameters

None

Return Value

None

Example

From sample file: 12f1840_ws2812b_spi.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with MSSP SPI interface
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 12F1840 with INTOSC at Fosc = 32 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 12f1840

-- Internal oscillator at 8 MHz with PLL enabled -> 32 MHz
pragma target clock    32_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target WDT      DISABLED           -- watchdog off
pragma target PWRTE    ENABLED            -- power up delay
pragma target MCLR     EXTERNAL           -- reset externally
pragma target BROWNOUT DISABLED           -- no brownout
pragma target CLKOUTEN DISABLED           -- no clock out
pragma target IESO     DISABLED           -- no osc switchover
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target LVP      ENABLED            -- allow LVP

OSCCON_IRCF   = 0b1110                    -- 8 MHz (+ PLL -> 32 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
-- OSCCON_PLLEN  = TRUE                   -- PLL fixed enabled by configuration bits

enable_digital_io()                       -- all pins digital

alias led is pin_A2                       -- being alive signal
pin_A2_direction = output
led = ON

APFCON_SDOSEL = 0                         -- pin_SDO configured on pin_A0
pin_SDO_RA0_direction = OUTPUT            -- configure SDO pin for (digital) output

const WS2812B_NUM = 30

include ws2812b_spi                       -- support library (MSSP SPI variant)
ws2812b_spi_init()                        -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: ws2812b_spi.jal


ws2812b_sw.jal - JALLIB Library Documentation

ws2812b_sw.jal JALLIB LIBRARY

Title

Library to support a chain of WS2812B chips by bit-banging

Author

Rob Hamerling, Copyright (c) 2014..2014, all rights reserved., Adapted-by:

Compiler

2.4q2

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to control a chain of WS2812Bs
This library uses 'bit banging' to transfer data to the WS2812Bs.
- A PIC with Fosc of at least 32 MHz is required.
- The user program must specify an alias for the control pin, like:
alias pin_WS2812B is pin_A1 -- pin_A1 used for WS2812B control
and the chosen pin must be configured for digital output.
- The number of WS2812Bs in the chain must be specified, like:
const byte WS2812B_NUM = 30 -- for 30 chained WS2812Bs
- The user program should contain 3 byte arrays of WS2812B_NUM bytes each, e.g.:
var byte agreen[WS2812B_NUM]
var byte ared[WS2812B_NUM]
var byte ablue[WS2812B_NUM]
and call the procedure ws2812b_refresh() to pass the current color settings
in these arrays to the WS2812B LEDs.
- Procedure ws2812b_all_color() can be used to set all LEDs to the same color
while keeping the color settings in the array unchanged.
Dependencies: ws2812b_common.jal

Notes

-----------------------------------------------------------------------------

========= 'private' procedures =====================

--- transfer a '0' WS2812B bit to the chain

Routines

  • _transfer_bit_0 - Procedure
  • _transfer_bit_1 - Procedure
  • _ws2812b_write_pixel - Procedure
  • ws2812b_sw_init - Procedure


ws2812b_sw_init - JALlib Procedures Help

ws2812b_sw_init JALLIB PROCEDURE

Signature

procedure ws2812b_sw_init() is

Description

Title: Initialize the Software ws2812b interface
Input: (none)
Notes: No initialization needed, procedure here just for uniformity

Include

To use this procedure, include the library:

include ws2812b_sw

Parameters

None

Return Value

None

Example

From sample file: 18f25k22_ws2812b_sw.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with bit-banging interface
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 18f25k22 with INTOSC at Fosc = 64 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 18f25k22

-- Internal oscillator at 16 MHz with PLL enabled -> 64 MHz
pragma target clock    64_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target PCLKEN   ENABLED            -- primary clock
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target IESO     DISABLED           -- no osc switchover
pragma target PWRTE    ENABLED            -- power up delay
pragma target BROWNOUT DISABLED           -- no brownout
pragma target WDT      CONTROL            -- watchdog software controlled
pragma target HFOFST   ENABLED            -- wait for stable osc
pragma target MCLR     EXTERNAL           -- reset externally
pragma target LVP      ENABLED            -- allow LVP
pragma target DEBUG    DISABLED           -- no debug

WDTCON_SWDTEN = DISABLED                  -- WDT disabled

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled

enable_digital_io()                       -- all pins digital

alias led is pin_A0                       -- being alive signal
pin_A0_direction = OUTPUT
led = ON

alias pin_WS2812B is pin_C5
pin_C5_direction = output

const WS2812B_NUM = 30

include ws2812b_sw                        -- support library (bit-banging variant)
ws2812b_sw_init()                         -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: ws2812b_sw.jal


ws2812b_sync.jal - JALLIB Library Documentation

ws2812b_sync.jal JALLIB LIBRARY

Title

Transmit a byte (with 3 WS2812B 'bits')

Author

Rob Hamerling, Copyright (c) 2014..2016, all rights reserved., Adapted-by: Rob Hamerling

Compiler

2.4q6

Licenses

Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)

Description

Library to control a chain of WS2812Bs
This library uses the USART module with master SYNC protocol.
- A PIC with Fosc of at least 32 MHz is required.
- A high speed USART is required (BRG16 bit in BAUDCON).
- The first or only USART interface is used and initialized automatically.
- The DIN wire of the WS2812B must be connected to pin_RX/DT of the PIC.
- The pin_RX/DT may have to be configured with Peripheral Pin Select (PPS)
or Alternate Pin Function (APFCON_RXDTSEL),
(the clock pin is not used).
- Because the WS2812b requires low-level for reset and the (E)USART
keeps RXDT high-level in idle-state an external polarity inverter is
required. The library generates an 'inverted' bitstream.
- The number of WS2812Bs in the chain must be defined with a constant:
const WS2812B_NUM = 30 -- for 30 chained WS2812Bs
- The user program should contain 3 byte arrays of WS2812B_NUM bytes each,
one for green, one for red, one for blue, e.g.:
var byte agreen[WS2812B_NUM]
var byte ared[WS2812B_NUM]
var byte ablue[WS2812B_NUM]
- Initialize the interface with procedure ws2812b_sync_init().
- Procedure ws2812b_refresh() is used to pass the current color settings
to the WS2812B LEDs.
- Procedure ws2812b_all_color() can be used to give all LEDs the same
color (or clear all leds with intensity 0) while keeping
the color settings in the arrays unchanged.
Dependencies: ws2812b_common.jal

Notes

- Warnings are temporary(?) commented out.
-----------------------------------------------------------------------------

========= 'private' procedures =====================

----------------------------------------------------------------------------
- We do not wait for completion after a write, but we need
to wait for TXREG being empty before transfer of data.
----------------------------------------------------------------------------

Routines

  • _transfer_byte - Procedure
  • _ws2812b_write_pixel - Procedure
  • ws2812b_refresh - Procedure
  • ws2812b_sync_init - Procedure


ws2812b_sync_init - JALlib Procedures Help

ws2812b_sync_init JALLIB PROCEDURE

Signature

procedure ws2812b_sync_init() is

Description

Title: Initialize the USART for Synchronous transmit at the required speed
Input: (none)
Notes: Transmit mode only (clock pin not really used)
Baudrate rounded up (too fast works better than too slow)

Include

To use this procedure, include the library:

include ws2812b_sync

Parameters

None

Return Value

None

Example

From sample file: 18f25k22_ws2812b_sync.jal

-- ------------------------------------------------------
-- Title: Test a chain of WS2812B chips with USART Synchronous interface
--
-- Author: Rob Hamerling, Copyright (c) 2014..2014, all rights reserved.
--
-- Adapted-by:
--
-- Compiler: 2.4q3
--
-- This file is part of jallib  (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: 18f25k22 with INTOSC at Fosc = 64 MHz
--              to demonstrate the use of WS2812B libraries.
--
-- Sources:
--
-- Notes:
--
-- ------------------------------------------------------

-- chip setup
include 18f25k22

-- Internal oscillator at 16 MHz with PLL enabled -> 64 MHz
pragma target clock    64_000_000         -- oscillator frequency

pragma target OSC      INTOSC_NOCLKOUT    -- internal oscillator
pragma target PLLEN    ENABLED            -- PLL enabled
pragma target PCLKEN   ENABLED            -- primary clock
pragma target FCMEN    DISABLED           -- no clock monitoring
pragma target IESO     DISABLED           -- no osc switchover
pragma target PWRTE    ENABLED            -- power up delay
pragma target BROWNOUT DISABLED           -- no brownout
pragma target WDT      CONTROL            -- watchdog software controlled
pragma target HFOFST   ENABLED            -- wait for stable osc
pragma target MCLR     EXTERNAL           -- reset externally
pragma target LVP      ENABLED            -- allow LVP
pragma target DEBUG    DISABLED           -- no debug

WDTCON_SWDTEN = DISABLED                  -- WDT disabled

OSCCON_IRCF   = 0b111                     -- 16 MHz (+ PLL -> 64 MHz)
OSCCON_SCS    = 0b00                      -- Clock determined by fuses
OSCTUNE_PLLEN = TRUE                      -- PLL enabled

enable_digital_io()                       -- all pins digital

alias led is pin_A0                       -- being alive signal
pin_A0_direction = OUTPUT
led = ON

const WS2812B_NUM = 30

include ws2812b_sync                      -- support library (USART SYNC variant)
ws2812b_sync_init()                       -- initialize

-- --- Program ---

var byte agreen[WS2812B_NUM]              -- green array
var byte ared[WS2812B_NUM]                -- red array
var byte ablue[WS2812B_NUM]               -- blue array
var byte g0, r0, b0

var byte i

-- --- increasing luninosity of white ---
for (127) using i loop                    -- increasing luminosity
   ws2812b_all_color(i,i,i)               -- white
   delay_1ms(35)
end loop

-- --- different basic colors ---
ws2812b_all_color(63,0,0)                 -- green
delay_100ms(15)
ws2812b_all_color(0,63,0)                 -- red
delay_100ms(15)
ws2812b_all_color(0,0,63)                 -- blue
delay_100ms(15)

-- --- initialize the arrays with color patterns ---
for (WS2812B_NUM) using i loop            -- init pattern
   agreen[i] = ((i / 8) * 64)
   ared[i]   = ((i / 4) * 64)
   ablue[i]  = ((i    ) * 64)
end loop

-- --- walking lights with changing color pattern ---
forever loop
   ws2812b_refresh(agreen, ared, ablue)
   for (WS2812B_NUM - 1) using i loop     -- modify led pattern
      agreen[i] = agreen[i+1]
      ared[i]   = ared[i+1]
      ablue[i]  = ablue[i+1]
   end loop
   agreen[WS2812B_NUM - 1] = (agreen[WS2812B_NUM - 1] + 10) & 0x7F
   ared[WS2812B_NUM - 1]   = (ared[WS2812B_NUM - 1]   - 20) & 0x7F
   ablue[WS2812B_NUM - 1]  = (ablue[WS2812B_NUM - 1]  + 30) & 0x7F
   led = !led
   delay_1ms(125)
end loop

Generated by JALlib CHM Help System | Source: ws2812b_sync.jal


x9c10x_init - JALlib Procedures Help

x9c10x_init JALLIB PROCEDURE

Signature

procedure x9c10x_init() is

Description

Inititialize wiper and put it at X9C10X_MIN_VALUE.

Include

To use this procedure, include the library:

include digital_potentiometer_x9c10x

Parameters

None

Return Value

None

Example

From sample file: 16f877_digital_potentiometer_x9c10x.jal

-- Title: Digital potentiometer mcp4131 sample
-- Author: Matthew Schinkel - borntechi.com, copyright (c) 2009..2020, all rights reserved.
-- Adapted-by: Rob Jansen
-- Compiler: >=2.5r4
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)
--
-- Description: This sample controls digital potentiometer X9C102, X9C103, X9C104, X9C503.
--
-- Sources: Renesas datasheet for X9C102, X9C103, X9C104, X9C503.
--
-- This file has been generated by Matt's sample generator but manually modfied
-- by Rob Jansen for use with digital_potentiometer_x9c10x.jal
--

include 16f877                      -- target PICmicro
--
-- This program assumes that a 20 MHz resonator or crystal
-- is connected to pins OSC1 and OSC2.
-- (unspecified configuration bits may cause a different frequency!)
pragma target clock 20_000_000      -- oscillator frequency
--
pragma target OSC      HS           -- crystal or resonator
pragma target WDT      DISABLED     -- watchdog
pragma target DEBUG    DISABLED     -- no debugging
pragma target LVP      ENABLED      -- allow Low Voltage Programming
--
-- The configuration bit settings above are only a selection, sufficient
-- for this program, but other programs may need more or different settings.
--
enable_digital_io()                 -- make all pins digital I/O
_usec_delay (100_000) -- wait for power to stablilize

-- x9c10x pin definition.
alias x9c10x_increment_pin             is pin_A2
alias x9c10x_increment_pin_direction   is pin_A2_direction
alias x9c10x_up_down_pin               is pin_A4
alias x9c10x_up_down_pin_direction     is pin_A4_direction
alias x9c10x_chip_select_pin           is pin_A5
alias x9c10x_chip_select_pin_direction is pin_A5_direction

-- Include the potentiometer library and intialize which set the wiper to the
-- minimal position.
include digital_potentiometer_x9c10x
x9c10x_init()

alias pot_wiper     is x9c10x_wiper
alias pot_increment is x9c10x_increment
alias pot_decrement is x9c10x_decrement
alias pot_store     is x9c10x_store

pot_wiper = 0 -- set wiper to zero
var byte step = 0

forever loop
   pot_wiper = step
   step = step + 1

;   for 255 loop
;      pot_increment()
;   end loop
;   for 255 loop
;      pot_decrement()
;   end loop
end loop

Generated by JALlib CHM Help System | Source: digital_potentiometer_x9c10x.jal


xbee_api.jal - JALLIB Library Documentation

xbee_api.jal JALLIB LIBRARY

Title

Xbee API operaiton library

Author

Sebastien Lelong, Copyright (c) 2012, all rights reserved., Adapted-by:

Compiler

2.4o

Licenses

Released under the BSD license (http://www.opensource.org/licenses/bsd-license.php)

Description

access Xbee in API mode

Notes

Xbee series 2 only

Must-Be-Predefined

Defaults

Sources

mainly inspired by http://code.google.com/p/xbee-arduino/

Constants and Variables

XBEE_PAYLOAD_SIZE - const byte = 32 -- message will be 32 chars length
message will be 32 chars length
XBEE_ATAP - const byte = 2
XBEE_START_BYTE - const byte = 0x7e
XBEE_ESCAPE - const byte = 0x7d
XBEE_XON - const byte = 0x11
XBEE_XOFF - const byte = 0x13
XBEE_MAX_FRAME_DATA_SIZE - const byte = 110
XBEE_BROADCAST_ADDRESS - const word = 0xffff
XBEE_ZB_BROADCAST_ADDRESS - const word = 0xfffe
XBEE_ZB_TX_API_LENGTH - const byte = 12
XBEE_TX_16_API_LENGTH - const byte = 3
XBEE_TX_64_API_LENGTH - const byte = 9
XBEE_AT_COMMAND_API_LENGTH - const byte = 2
XBEE_REMOTE_AT_COMMAND_API_LENGTH - const byte = 13
XBEE_PACKET_OVERHEAD_LENGTH - const byte = 6
XBEE_API_ID_INDEX - const byte = 3
XBEE_RX_16_RSSI_OFFSET - const byte = 2
XBEE_RX_64_RSSI_OFFSET - const byte = 8
XBEE_DEFAULT_FRAME_ID - const byte = 1
XBEE_NO_RESPONSE_FRAME_ID - const byte = 0
XBEE_ACK_OPTION - const byte = 0
XBEE_DISABLE_ACK_OPTION - const byte = 1
XBEE_BROADCAST_OPTION - const byte = 4
XBEE_ZB_PACKET_ACKNOWLEDGED - const byte = 0x01
XBEE_ZB_BROADCAST_PACKET - const byte = 0x02
XBEE_TX_64_REQUEST - const byte = 0x0
XBEE_TX_16_REQUEST - const byte = 0x1
XBEE_AT_COMMAND_REQUEST - const byte = 0x08
XBEE_AT_COMMAND_QUEUE_REQUEST - const byte = 0x09
XBEE_REMOTE_AT_REQUEST - const byte = 0x17
XBEE_ZB_TX_REQUEST - const byte = 0x10
XBEE_ZB_EXPLICIT_TX_REQUEST - const byte = 0x11
XBEE_RX_64_RESPONSE - const byte = 0x80
XBEE_RX_16_RESPONSE - const byte = 0x81
XBEE_RX_64_IO_RESPONSE - const byte = 0x82
XBEE_RX_16_IO_RESPONSE - const byte = 0x83
XBEE_AT_RESPONSE - const byte = 0x88
XBEE_TX_STATUS_RESPONSE - const byte = 0x89
XBEE_MODEM_STATUS_RESPONSE - const byte = 0x8a
XBEE_ZB_RX_RESPONSE - const byte = 0x90
XBEE_ZB_EXPLICIT_RX_RESPONSE - const byte = 0x91
XBEE_ZB_TX_STATUS_RESPONSE - const byte = 0x8b
XBEE_ZB_IO_SAMPLE_RESPONSE - const byte = 0x92
XBEE_ZB_IO_NODE_IDENTIFIER_RESPONSE - const byte = 0x95
XBEE_AT_COMMAND_RESPONSE - const byte = 0x88
XBEE_REMOTE_AT_COMMAND_RESPONSE - const byte = 0x97
XBEE_SUCCESS - const byte = 0x0
XBEE_CCA_FAILURE - const byte = 0x2
XBEE_INVALID_DESTINATION_ENDPOINT_SUCCESS - const byte = 0x15
XBEE_NETWORK_ACK_FAILURE - const byte = 0x21
XBEE_NOT_JOINED_TO_NETWORK - const byte = 0x22
XBEE_SELF_ADDRESSED - const byte = 0x23
XBEE_ADDRESS_NOT_FOUND - const byte = 0x24
XBEE_ROUTE_NOT_FOUND - const byte = 0x25
XBEE_PAYLOAD_TOO_LARGE - const byte = 0x74
XBEE_HARDWARE_RESET - const byte = 0
XBEE_WATCHDOG_TIMER_RESET - const byte = 1
XBEE_ASSOCIATED - const byte = 2
XBEE_DISASSOCIATED - const byte = 3
XBEE_SYNCHRONIZATION_LOST - const byte = 4
XBEE_COORDINATOR_REALIGNMENT - const byte = 5
XBEE_COORDINATOR_STARTED - const byte = 6
XBEE_ZB_BROADCAST_RADIUS_MAX_HOPS - const byte = 0
XBEE_ZB_TX_UNICAST - const byte = 0
XBEE_ZB_TX_BROADCAST - const byte = 8
XBEE_AT_OK - const byte = 0
XBEE_AT_ERROR - const byte = 1
XBEE_AT_INVALID_COMMAND - const byte = 2
XBEE_AT_INVALID_PARAMETER - const byte = 3
XBEE_AT_NO_RESPONSE - const byte = 4
XBEE_NO_ERROR - const byte = 0
XBEE_CHECKSUM_FAILURE - const byte = 1
XBEE_PACKET_EXCEEDS_BYTE_ARRAY_LENGTH - const byte = 2
XBEE_UNEXPECTED_START_BYTE - const byte = 3
xbee - var xbee_main
xbee_res - var xbee_response
xbee_req - var xbee_request

Routines

  • _xbee_res_get_packet_length - Function returns byte
  • _xbee_res_init - Procedure
  • _xbee_res_reset - Procedure
  • _xbee_reset_response - Procedure
  • print_xbee_response - Procedure
  • xbee_init - Procedure
  • xbee_read_packet - Procedure
  • xbee_receive - Procedure
  • xbee_req_get_frame_data - Function returns byte
  • xbee_req_get_frame_data_length - Function returns byte
  • xbee_req_payload'put - Procedure
  • xbee_res_payload'get - Function returns byte
  • xbee_send - Procedure
  • xbee_send_byte - Procedure
  • xbee_write_packet - Procedure


xbee_init - JALlib Procedures Help

xbee_init JALLIB PROCEDURE

Signature

procedure xbee_init() is

Description

must be called once lib is included

Include

To use this procedure, include the library:

include xbee_api

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_xbee_api_rx.jal

-- Title: XBee API receiving sample
-- Author: Sebastien Lelong, Copyright (c) 2012, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: this sample show how to use xbee_api library to receive
-- data through XBee in API mode.
-- See tutorial here:
--  - http://jaluino.org/building-xbee-network-part-1
--  - http://jaluino.org/building-xbee-network-part-2
-- Derived from a Jaluino sample
--
-- This file has been generated by hand (manually maintained)
--

-- Xtal 16MHz w/ PLL, system clock 48MHz
include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

alias onboard_led is pin_C2
alias onboard_led_direction is pin_C2_direction

include delay
include print

const serial_hw_baudrate = 9_600
include serial_hardware
serial_hw_init()
alias xbee_carrier is serial_hw_data

-- we'll output received data through the other serial module
-- configure pins through PPS as:
--  * B7 <= RX2
--  * B6 => TX2
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- TX2 is an output function: we assign a function to a RP pin (here RP9)
PPS_MAP_RP9 = PPS_TX2CK2
-- RX2 is an input function: we assign a RP pin the a function register
PPS_MAP_RX2DT2 = RP10
-- PPS configuration is done, we can lock again to apply changes
pps_control_lock(true)
-- declare aliases for the remapped RX2 and TX2 pins
alias pin_RX2            is  pin_RP10
alias pin_RX2_direction  is  pin_RP10_direction
alias pin_TX2            is  pin_RP9
alias pin_TX2_direction  is  pin_RP9_direction
const SERIAL_HW2_BAUDRATE = 115_200
include serial_hardware2
serial_hw2_init()

const byte XBEE_PAYLOAD_SIZE = 2
include xbee_api
xbee_init()

-- (for the record)
-- Me, the source Xbee has the following addresses
-- SH: 13A200
-- SL: 4054F82F

-- Assuming LED is enable on hajumper)
onboard_led_direction =  output
-- receving loop
forever loop

   var byte i

   xbee_read_packet()
   const byte msg[] = "--Response--"
   const byte api_id[] = "api_id: "
   const byte frame_id[] = "frame_id: "
   const byte frame_data[] = "frame_data: "
   const byte msb_length[] = "msb_length: "
   const byte lsb_length[] = "lsb_length: "
   const byte checksum[] = "checksum: "
   const byte frame_length[] = "frame_length: "
   const byte complete[] = "complete: "
   const byte error_code[] = "error_code: "
   const byte payload[] = "payload: "

   print_string(serial_hw2_data,msg)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,api_id)
   print_byte_hex(serial_hw2_data,xbee_res.api_id)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,frame_id)
   print_byte_hex(serial_hw2_data,xbee_res.frame_id)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,msb_length)
   print_byte_hex(serial_hw2_data,xbee_res.msb_length)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,lsb_length)
   print_byte_hex(serial_hw2_data,xbee_res.lsb_length)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,frame_length)
   print_byte_hex(serial_hw2_data,xbee_res.frame_length)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,checksum)
   print_byte_hex(serial_hw2_data,xbee_res.checksum)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,complete)
   print_bit_logic(serial_hw2_data,xbee_res.complete)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,error_code)
   print_byte_hex(serial_hw2_data,xbee_res.error_code)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,frame_data)
   for xbee_res.frame_length using i loop
       print_byte_hex(serial_hw2_data,xbee_res.frame_data[i])
   end loop
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,payload)
   for XBEE_PAYLOAD_SIZE loop
       serial_hw2_data = xbee_res_payload
   end loop
   print_crlf(serial_hw2_data)

end loop

Generated by JALlib CHM Help System | Source: xbee_api.jal


xbee_read_packet - JALlib Procedures Help

xbee_read_packet JALLIB PROCEDURE

Signature

procedure xbee_read_packet() is

Description

Read a full packet, fill in xbee_res response. This may be a blocking call
as underlying data carrier may block until data is read (typically when
serial_hw_data is involved here).
Once called, you may check xbee_res.error_code = 0 to make sure everything
if fine. You may also check xbee_res.api_id value (see constants at the
beginning) to know what lind of response it is (rx, tx_status, etc...)

Include

To use this procedure, include the library:

include xbee_api

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_xbee_api_rx.jal

-- Title: XBee API receiving sample
-- Author: Sebastien Lelong, Copyright (c) 2012, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: this sample show how to use xbee_api library to receive
-- data through XBee in API mode.
-- See tutorial here:
--  - http://jaluino.org/building-xbee-network-part-1
--  - http://jaluino.org/building-xbee-network-part-2
-- Derived from a Jaluino sample
--
-- This file has been generated by hand (manually maintained)
--

-- Xtal 16MHz w/ PLL, system clock 48MHz
include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

alias onboard_led is pin_C2
alias onboard_led_direction is pin_C2_direction

include delay
include print

const serial_hw_baudrate = 9_600
include serial_hardware
serial_hw_init()
alias xbee_carrier is serial_hw_data

-- we'll output received data through the other serial module
-- configure pins through PPS as:
--  * B7 <= RX2
--  * B6 => TX2
include pps
-- PPS module writes are protected, we need to first unlock it
pps_control_lock(false)
-- TX2 is an output function: we assign a function to a RP pin (here RP9)
PPS_MAP_RP9 = PPS_TX2CK2
-- RX2 is an input function: we assign a RP pin the a function register
PPS_MAP_RX2DT2 = RP10
-- PPS configuration is done, we can lock again to apply changes
pps_control_lock(true)
-- declare aliases for the remapped RX2 and TX2 pins
alias pin_RX2            is  pin_RP10
alias pin_RX2_direction  is  pin_RP10_direction
alias pin_TX2            is  pin_RP9
alias pin_TX2_direction  is  pin_RP9_direction
const SERIAL_HW2_BAUDRATE = 115_200
include serial_hardware2
serial_hw2_init()

const byte XBEE_PAYLOAD_SIZE = 2
include xbee_api
xbee_init()

-- (for the record)
-- Me, the source Xbee has the following addresses
-- SH: 13A200
-- SL: 4054F82F

-- Assuming LED is enable on hajumper)
onboard_led_direction =  output
-- receving loop
forever loop

   var byte i

   xbee_read_packet()
   const byte msg[] = "--Response--"
   const byte api_id[] = "api_id: "
   const byte frame_id[] = "frame_id: "
   const byte frame_data[] = "frame_data: "
   const byte msb_length[] = "msb_length: "
   const byte lsb_length[] = "lsb_length: "
   const byte checksum[] = "checksum: "
   const byte frame_length[] = "frame_length: "
   const byte complete[] = "complete: "
   const byte error_code[] = "error_code: "
   const byte payload[] = "payload: "

   print_string(serial_hw2_data,msg)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,api_id)
   print_byte_hex(serial_hw2_data,xbee_res.api_id)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,frame_id)
   print_byte_hex(serial_hw2_data,xbee_res.frame_id)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,msb_length)
   print_byte_hex(serial_hw2_data,xbee_res.msb_length)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,lsb_length)
   print_byte_hex(serial_hw2_data,xbee_res.lsb_length)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,frame_length)
   print_byte_hex(serial_hw2_data,xbee_res.frame_length)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,checksum)
   print_byte_hex(serial_hw2_data,xbee_res.checksum)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,complete)
   print_bit_logic(serial_hw2_data,xbee_res.complete)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,error_code)
   print_byte_hex(serial_hw2_data,xbee_res.error_code)
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,frame_data)
   for xbee_res.frame_length using i loop
       print_byte_hex(serial_hw2_data,xbee_res.frame_data[i])
   end loop
   print_crlf(serial_hw2_data)
   --
   print_string(serial_hw2_data,payload)
   for XBEE_PAYLOAD_SIZE loop
       serial_hw2_data = xbee_res_payload
   end loop
   print_crlf(serial_hw2_data)

end loop

Generated by JALlib CHM Help System | Source: xbee_api.jal


xbee_send - JALlib Procedures Help

xbee_send JALLIB PROCEDURE

Signature

procedure xbee_send() is

Description

Send a request and read tx_status response. If delivery failed, try again
(until if works...)

Include

To use this procedure, include the library:

include xbee_api

Parameters

None

Return Value

None

Example

From sample file: 18f27j53_xbee_api_tx.jal

-- Title: Sending data using Xbee API mode
-- Author: Sebastien Lelong, Copyright (c) 2012, all rights reserved.
-- Adapted-by: Rob Hamerling
-- Compiler: 2.4q2
--
-- This file is part of jallib (https://github.com/jallib/jallib)
-- Released under the ZLIB license (http://www.opensource.org/licenses/zlib-license.html)
--
-- Description: show how to send data through Xbee in API operation.
-- See tutorial here:
--  - http://jaluino.org/building-xbee-network-part-1
--  - http://jaluino.org/building-xbee-network-part-2
-- Derived from a Jaluino sample
--
-- This file has been generated by hand (manually maintained)
--

-- Xtal 16MHz w/ PLL, system clock 48MHz
include 18f27j53
pragma target clock 48_000_000   -- oscillator frequency
-- magical statements
pragma target PLLDIV    P4
pragma target CPUDIV    P1
pragma target PLLEN  disabled    -- PLL via fuse turned off
pragma target OSC    HS_PLL
OSCTUNE_PLLEN = on               -- PLL via OSCTUNE enabled
pragma target WDT    control     -- watchdog
WDTCON_SWDTEN = off              -- no watchdog
-- declare secondary oscillator on T1OSI/T1OSO pins
pragma target RTCOSC T1OSC
pragma target SOSCSEL HP
_usec_delay(2000) -- PLL needs 2ms before stable

enable_digital_io()

alias onboard_led is pin_C2
alias onboard_led_direction is pin_C2_direction

include delay
include print

const serial_hw_baudrate = 9_600
include serial_hardware
serial_hw_init()

alias xbee_carrier is serial_hw_data
--alias xbee_carrier_data_available is serial_hw_data_available
const byte XBEE_PAYLOAD_SIZE = 2
include xbee_api
xbee_init()

-- define which XBee will receive the message
-- Dest. Xbee is connected to my PC, it's a coordinator
-- with firmware API AP=2. According to X-CTU tool:
-- SH: 13A200
-- SL: 40301109
-- 16bits address: 0
var xbee_address64 xbee_dest
xbee_dest.msb = 0x0013a200
xbee_dest.lsb = 0x40301109
var word xbee_net = 0xfffe -- I think it's a broadcast network address

-- (for the record)
-- Me, the source Xbee has the following addresses
-- SH: 13A200
-- SL: 4054F82F

xbee_req.addr64 = xbee_dest
xbee_req.network = xbee_net
xbee_req.api_id = XBEE_ZB_TX_REQUEST
xbee_req.frame_id = 1
-- also set the following, else it's working
-- when PIC gets prog'd, not after a power down/up
xbee_req.broadcast_radius = 0
xbee_req.option = 0

-- Assuming LED is enable on hajumper)
onboard_led_direction =  output

forever loop
   var byte i
   -- send 0:0,1:2,2:4,3:6, ...
   for 120 using i loop
      onboard_led = high

      -- prepare payload
      xbee_req.payload[0] = i
      xbee_req.payload[1] = i + 1
      xbee_send()

      delay_1s(1)
      onboard_led = low
      delay_1s(1)

   end loop
end loop

Generated by JALlib CHM Help System | Source: xbee_api.jal